Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

208
Visualizações
Immutable update pattern in react for nested data

Redux specifies that "The key to updating nested data is that every level of nesting must be copied and updated appropriately."

// changing reference in top level
const newState = {...oldState}
newState.x.y.z = 10;
setState(newState)

// or updating reference in all levels
const newState = {...oldState}
newState.x = {...newState.x}
newState.x.y = {..newState.x.y}
newState.x.y.z = 10

Is this is same for react, can't find the documentation regarding this on react.

about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

Yes, you should apply this concept when updating your state in React also. If you don't, you can have issues with components not re-rendering when you update your state. Normally, React will rerender your component when your state changes, in both of your examples you're doing this, as you're creating a new object reference at the top-level which will cause React to rerender your component and any of its child components (ie: the children components also get rerender when the parent component rerenders). However, there is an exception to this. If you've memoized a component to help with efficiency using React.memo(), your memoized child component will only update when the props that it's passed change. If you are passing a child component an object that is nested within your original state, React won't rerender that component unless that object reference has changed. This could lead to issues if your memoized children components are trying to use state from your parent component.

For example:

const { useState, memo } = React;
const App = () => {
  const [state, setState] = useState({
    x: {
      y: {
        z: 0
      }
    }
  });
  
  const changeStateBad = () => {
    // Your first technique (can cause issues)
    const newState = {...state};
    newState.x.y.z += 1;
    setState(newState);
  }
  
  const changeStateGood = () => {
    // Your second technique for updating at all levels (just rewritten slightly)
    const newState = {
      ...state,
      x: {
        ...state.x,
        y: {
          ...state.x.y,
          z: state.x.y.z + 1
        }
      }
    };

    setState(newState);
  }
  
  return <div>
    <NumberDisplay x={state.x} />
    <br />
    <button onClick={changeStateGood}>Good update</button>
    <br />
    <button onClick={changeStateBad}>Bad update</button>
  </div>
}

// A memoized component that only rerenders when its props update
const NumberDisplay = memo(({x}) => {
  return <h1>{x.y.z}</h1>;
});

ReactDOM.render(<App />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>

about 4 years ago · Juan Pablo Isaza Relatório

0

data types in JS can be divided into primitive data types (eg. string, number) and non-primitive data types (eg. object),

primitive data types can not be modified (eg. using String.prototype.replace will always return a new instance of a string) while non-primitive data types can - and the reference pointing to that data will be "updated" as well (that's a big simplification, but executing eg. x.y = 2 will not create a new instance of x - instead the x will be keept the same in every place it's referenced),

which means to detect a change in the new version of the state (in a most performant way) it is required to create a new instance of an Object, Array (and other non-primitive data type representations)

// changing reference in top level
const newState = { ...oldState }

// changing nested reference
const newState = {
    ...oldState,
    x: {
        ...oldState.x,
        y: 2 // new "y" value
    }
}

// changing nested reference, another example
const newState = {
    ...oldState,
    x: {
        ...oldState.x,
        y: {
            ...oldState.x.y,
            z: 'test' // new "z" value
        }
    }
}

you can read more how change is detected on a basic level here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#comparing_objects

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda