При доступе к текущему состоянию внутри вызова setState () React Hook, является ли переменная prevState копией или прямой ссылкой на объект состояния? - PullRequest
2 голосов
/ 26 июня 2019

Представьте, что нам нужно обновить какое-то свойство внутри объекта в состоянии. Также нам нужно сохранить другие свойства без изменений.

const [myState,setMyState] = React.useState({propA: 'FOO'})

Я обычно делаю что-то вроде этого:

function update() {
  setMyState((prevState) => {
    // IS 'prevState' A SHALLOW COPY OR A DIRECT REFERENCE TO THE SAME OBJECT
  });
}

ВОПРОС

Является ли prevState мелкой копией или прямой ссылкой на тот же объект? Если это прямая ссылка, это в основном тот же объект, верно?

1 Ответ

0 голосов
/ 26 июня 2019

Как видно из фрагмента ниже prevState является прямой ссылкой на объект текущего состояния. Другими словами, поскольку объекты в основном являются ссылками, prevState - это тот же объект, что и объект. текущее состояние.

Вы можете увидеть это поведение во фрагменте ниже:

Примечание: Обратите внимание, что когда вы обновляете состояние без поверхностного копирования состояния, вы изменяете объект состояния, но не запускаете повторную визуализацию, потому что реагирует только проверка ссылки на объект, и это остается тем же, потому что вы возвращаете тот же объект с той же ссылкой на него.

function App() {
  
  const[myState,setMyState] = React.useState({propA: 'FOO'});
  
  function handleClick() {
    console.clear();
    setMyState((prevState) => {
      console.log('myState: ' + JSON.stringify(myState));
      console.log('prevState: ' + JSON.stringify(prevState));
      console.log('Are "myState" and "prevState" the very same object: ' + JSON.stringify(prevState === myState));
      const shallowCopy = {...prevState}
      console.log('shallowCopy of prevState: ' + JSON.stringify(shallowCopy));
      console.log('Are "shallowCopy" and "prevState" the very same object: ' + JSON.stringify(shallowCopy === myState));
      return prevState;
    });
  }
  
  function updateWithShallowCopy() {
    setMyState((prevState)=>{
      const shallowCopy = {...prevState};
      shallowCopy.propA = 'BAR<-------------------------------------';
      return shallowCopy;
    });
  }
  
  function updateWithoutShallowCopy() {
    setMyState((prevState)=>{
      prevState.propA = 'BAR';
      return prevState;
    });
  }
  
  return(
    <React.Fragment>
      <div>{myState.propA}</div>
      <button onClick={handleClick}>Click to inspect</button>
      <button onClick={updateWithoutShallowCopy}>Update WITHOUT shallow copy</button>
      <button onClick={handleClick}>Click to inspect</button>
      <button onClick={updateWithShallowCopy}>Update WITH shallow copy</button>
      <div>Click in all buttons in order from left to right</div>
    </React.Fragment>
  );
}


ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"/>
...