Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

202
Views
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 answers
Answer question

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!