最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Does React make any guarantees that the `props` object reference stays stable? - Stack Overflow

programmeradmin0浏览0评论

Recently I saw code akin to the following contrived example:

const MyComp = props => {
  const [prevProps, setPrevProps] = useState(props)

  if (props !== prevProps) {
    setPrevProps(props);
    // do something else...
  }
}

The ponent uses some kind of derived state to remember the previous props. If the memory location of props has changed (props !== prevProps), it will sync the new props to useState.

Yeah, it doesn't make that much sense, but my point is: Does React make any guarantees, that the object reference of props stays the same, given no contained property of props has changed?

At least, this seems to be the case for the tests I have done. If a parent ponent changes any of the props, there will be a new props object created.

I would appreciate any official documentation link proving this.

Recently I saw code akin to the following contrived example:

const MyComp = props => {
  const [prevProps, setPrevProps] = useState(props)

  if (props !== prevProps) {
    setPrevProps(props);
    // do something else...
  }
}

The ponent uses some kind of derived state to remember the previous props. If the memory location of props has changed (props !== prevProps), it will sync the new props to useState.

Yeah, it doesn't make that much sense, but my point is: Does React make any guarantees, that the object reference of props stays the same, given no contained property of props has changed?

At least, this seems to be the case for the tests I have done. If a parent ponent changes any of the props, there will be a new props object created.

I would appreciate any official documentation link proving this.

Share Improve this question asked Mar 12, 2020 at 13:10 bela53bela53 3,4851 gold badge15 silver badges29 bronze badges 0
Add a ment  | 

1 Answer 1

Reset to default 9

Does React make any guarantees, that the object reference of props stays the same, given no contained property of props has changed?

No, it doesn't.

If a parent ponent changes any of the props, there will be a new props object created.

If the parent re-renders, the child will always receive its props in a new object, even if nothing in it has changed.

If you want to prevent that, you will have to use PureComponent or React.memo which will perform a shallow equal parison of all the properties of the props object and prevent re-rendering if none of them changed.

const { memo, useState, useEffect } = React;

const Child = props => {
  // only gets called when `props` changes
  useEffect(() => console.log(props.name, ": props changed"), [props]); 

  return <p>{props.name}: {props.text}</p>;
};

const MemoChild = memo(Child);

const Parent = () => {
  const [count, setCount] = useState(0);
  const [text, setText] = useState("foo");
  const handleTextChange = event => setText(event.target.value);

  return (
    <div>
      <button onClick={() => setCount(c => c + 1)}>
        Click to force Re-Render
      </button>
      <input id="text" value={text} onChange={handleTextChange} />
      <Child name="Child without memo()" text={text} />
      <MemoChild name="Child with memo()" text={text} />
    </div>
  );
};

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

Have a look at this example. You will see that when you press the button, the child not using memo will re-render, even if the props name or text have not changed. It will still receive a new props object.

But when you enter something into the input, both ponents re-render, because the text property of the props changed.

It should also be noted that this is only a performance optimization. You should not rely on memo preventing a re-render at all times.

This method only exists as a performance optimization. Do not rely on it to “prevent” a render, as this can lead to bugs.

发布评论

评论列表(0)

  1. 暂无评论