最近我看到类似于以下人为示例的代码:
const MyComp = props => {
const [prevProps, setPrevProps] = useState(props)
if (props !== prevProps) {
setPrevProps(props);
// do something else...
}
}
该组件使用某种派生状态来记住之前的 props。如果内存位置为props
已经改变 (props !== prevProps
),它将把新的 props 同步到useState
.
是的,这没有多大意义,但我的观点是:React 是否做出任何保证,props
保持不变,假设没有包含属性props
已经改变?
至少,我所做的测试似乎是这样。如果父组件更改任何 props,将会有一个新的props
对象已创建。
我将不胜感激任何证明这一点的官方文档链接。
如果 props 包含的属性没有改变,React 是否保证 props 的对象引用保持不变?
不,事实并非如此。
如果父组件更改任何 props,将会创建一个新的 props 对象。
如果父级重新渲染,孩子将始终在新对象中接收其道具,即使其中没有任何改变。
如果你想阻止这种情况,你将不得不使用PureComponent
or React.memo https://reactjs.org/docs/react-api.html#reactmemo这将对所有属性进行浅层相等比较props
对象并防止重新渲染(如果它们都没有改变)。
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.com/ajax/libs/react/16.13.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>
看看这个例子。你会看到当你按下按钮时,孩子没有使用memo
会重新渲染,即使 propsname
or text
没有改变。仍然会收到新的props
object.
但是当您在输入中输入某些内容时,两个组件都会重新渲染,因为text
道具的属性发生了变化。
还应该注意的是,这只是性能优化。你不应该依赖memo
始终防止重新渲染。
该方法仅作为性能优化 https://reactjs.org/docs/optimizing-performance.html。不要依赖
它是为了“阻止”渲染,因为这可能会导致错误。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)