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

319
Views
What is the status of the 'default props rerender' trap in React?

I'm looking for a canonical reference to how this has been dealt with.

If I have a component that looks like this:


const MyComponent = ({ value = [] }) => {
  const [otherValue, setOtherValue] = React.useState([]);

  React.useEffect(() => {
    setOtherValue(value);
  }, [value]);


  return <div> doesn't matter</div>
};

What happens is:

  1. When value changes, the useEffect callback fires, and this calls a setState
  2. The setState causes a rerender, if value is nullish, then the default array is assigned, and this is a new object, and so this in turn, causes a rerender.
  3. Infinite loop.

The solution can be to declare your default prop as a constant, like:

const DEFAULT_VALUE = []; 
const MyComponent = ({ value = DEFAULT_VALUE }) => {
  const [otherValue, setOtherValue] = React.useState([]);

My questions:

For each of the version 16, 17, 18 of React:

  • Is this an issue that has been solved? If, so which version solved it?
  • If it hasn't been solved, a pointer to the 'won't solve' decision.
  • Is there an eslint rule to capture this?
  • Anything else that is generally helpful in avoiding this trap.
over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

You can use a property called defaultProps. With defaultProps the default value of your property become part of the definition the component and is no longer reseted at every render, preventing the infinity loop with useEffect. So it will be something like that:

const MyComponent = ({ value }) => {
  const [otherValue, setOtherValue] = React.useState([]);

  React.useEffect(() => {
    setOtherValue(value);
  }, [value]);


  return <div> doesn't matter</div>
};

MyComponent.defaultProps = {
  value: []
};

And yes, there is an lint rule for that, but the rule is:

Enforce a defaultProps definition for every prop that is not a required prop

So it is not exactly what you want because it works with prop-types rules but I think will help you with it. If you wanna see more details about this rule here is the readme describing it.

over 4 years ago · Santiago Trujillo Report

0

The infinite loop is not related to ReactJS, so it couldn't be fixed by any versions. the issue returns to primitive/reference values.

When you are using this:

const MyComponent = ({ value = [] }) => {
  const [otherValue, setOtherValue] = React.useState([]);

  React.useEffect(() => {
    setOtherValue(value);
  }, [value]); 

For even one change from props, if the next value is undefined javascript create a new value [] and assign it to value and React.useEffect thinks it's new (actually this thought is correct) and tries to get the new prop and compare with the last one and for any of these actions use value and each time it is new because its reference is new.

But your solution is awesome, for any reference type values we must cache it and then use it to avoid creating it over and over:

const DEFAULT_VALUE = []; 
const MyComponent = ({ value = DEFAULT_VALUE }) => {

ESLint:

There are some plugin rules to force developers to add default values in required or not-required props, but none of them hints you to cache the reference-type values for default props.

over 4 years ago · Santiago Trujillo 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!