Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

203
Vistas
Why I'm getting maximum update depth exceeded error when setting data to context (React)

In my React project I wanted to share the currency, which selected by the user, within the components using a context. Context functionality works fine, however, there is a small issue that I want to fix. It is setting default currency to the context. So, when the web is started at the very beginning there will be a default currency set to the context, which is going to come from the selection that is provided from the endpoint. I used an if-statement as shown in CurrencySelector.js but I was getting that error "Maximum Update Depth Exceeded." I provided my code for the context and currency selection component.

import React, { Component, createContext } from "react";

const CurrencyContext = createContext();

class CurrencyContextProvider extends Component {
  state = { selectedCurrency: "uuu" };
  setCurrency = (c) => {
    this.setState({ selectedCurrency: c });
  };

  render() {
    return (
      <CurrencyContext.Provider
        value={{ ...this.state, setCurrency: this.setCurrency }}
      >
        {this.props.children}
      </CurrencyContext.Provider>
    );
  }
}

class CurrencySelector extends React.Component {
  constructor(props) {
    super(props);
    console.log("CurrencySelector constructor");
    this.state = { currencies: [] };
  }

  async componentDidMount() {
    let currencies = (await this.getCurrencies()).data
      .currencies;
    this.setState({ currencies: currencies });
  }

  async getCurrencies() {
    return await fetchAnyQuery(`query{ currencies }`);
  }

  render() {
    return (
      <CurrencyContext.Consumer>
        {(currencyContext) => {
          const {
            selectedCurrency,
            setCurrency,
          } = currencyContext;
          return (
            <select
              name="currency-selector"
              onChange={(event) => {
                setCurrency(event.target.value);
              }}
            >
              {this.state.currencies.map((currency, index) => {
                //When I wrote this if-statement I got the error
                if (index == 0) {
                  setCurrency(currency);
                }
                return (
                  <option value={currency}>{currency}</option>
                );
              })}
            </select>
          );
        }}
      </CurrencyContext.Consumer>
    );
  }
}
about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

//When I wrote this if-statement I got the error
if (index == 0) {
  setCurrency(currency);
}

Yes – you would get an error, since you're mutating state during render, which is expressly forbidden. (This isn't specific to using a context.)

You have a couple options I can think of:

  • move the currency loading to the context provider, and have the context provider set the default currency once it's loaded the currencies
  • "fake" having a default currency set if one hasn't been set (but that will get hairy really quickly)

Here's an example of the first option.

See how getCurrencies() has been hoisted up to the componentDidMount() of the provider.

A bit of extra care will need to be applied, since it might be that the currencies haven't been loaded yet; see how we only render "Loading..." for that time.

import React, { Component, createContext } from "react";

const CurrencyContext = createContext();

// Fake fetcher function that just takes a bit of time.
function fetchAnyQuery() {
  return new Promise((resolve) =>
    setTimeout(() => resolve({ data: { currencies: ["a", "b", "c"] } }), 1000)
  );
}

class CurrencyContextProvider extends Component {
  state = { selectedCurrency: "uuu", currencies: undefined };
  setCurrency = (c) => {
    this.setState({ selectedCurrency: c });
  };

  async componentDidMount() {
    const currencies = (await this.getCurrencies()).data.currencies;

    this.setState(({ selectedCurrency }) => {
      if (!currencies.includes(selectedCurrency)) {
        // If the selected currency is invalid, reset it to the first one
        selectedCurrency = currencies[0];
      }
      return { currencies, selectedCurrency };
    });
  }

  async getCurrencies() {
    return await fetchAnyQuery(`query{ currencies }`);
  }

  render() {
    return (
      <CurrencyContext.Provider
        value={{ ...this.state, setCurrency: this.setCurrency }}
      >
        {this.state.currencies ? this.props.children : <>Loading...</>}
      </CurrencyContext.Provider>
    );
  }
}

class CurrencySelector extends React.Component {
  render() {
    return (
      <CurrencyContext.Consumer>
        {(currencyContext) => {
          const { selectedCurrency, currencies, setCurrency } = currencyContext;
          return (
            <div>
              <select
                name="currency-selector"
                value={selectedCurrency}
                onChange={(event) => {
                  setCurrency(event.target.value);
                }}
              >
                {currencies.map((currency) => (
                  <option value={currency} key={currency}>
                    {currency}
                  </option>
                ))}
              </select>
              <br />
              Selected: {selectedCurrency}
            </div>
          );
        }}
      </CurrencyContext.Consumer>
    );
  }
}

export default function App() {
  return (
    <CurrencyContextProvider>
      <CurrencySelector />
    </CurrencyContextProvider>
  );
}
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda