in react hooks, component works even without calling set state

Viewed 38

here is my react hooks code:

function State(){
  var [msg,set_msg]=React.useState("hello") //not rendered, just to force render
  var [data,set_data]=React.useState({version:1})
  function onClick(){
set_msg(x=>x+'x') //just to force render
data.version+=1   //changing state in place, but it still updates
  }
  return <div>
version={data.version}
<button {...{onClick}}>click</button>
  </div>
}
ReactDOM.render(<State />,document.querySelector('#root') );
  <div id="root"></div>

  <script src="https://unpkg.com/react@17/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <script type="text/babel" src="index.js"></script>  
    
<div id=root></root>
  

my question is: why does it work? the code does not set_data, just changes the version in place

1 Answers

Since you're using an object as the value of your state, you can change its properties without updating the state. This works because the state stores a reference to the object, not all of its values.

If you were to update the state in place (data.version+=1), it wouldn't force the component to re-render so no change would be visible, but the data would still have changed. Since you're forcing a render with the state change on the line before (which doesn't execute until the onClick function has been completed, the component reflects the change in data.

In summary, this actually works for storing and mutating data; it just won't actually render the component again. The only reason your component updates to reflect the change in data is because you force an update on the previous line.

Related