我需要比较prevProps的子代和当前props的子代,并且仅在componentDidUpdate方法中的代码不同时才执行代码。
当孩子是对象数组时,我如何比较他们?
componentDidUpdate(prevProps) {
if(!_.isEqual(prevProps.children, this.props.children)) {
console.log('not equal');
// execute some code
}
您可以简单地使用常规的等于运算符:
componentDidUpdate(prevProps) {
if (prevProps.children !== this.props.children) {
console.log('not equal');
}
}
这就是反应文档所说的。但是请注意,这只会检查数组是否不同。它不会检测数组中的对象是否已更改,但是由于react的工作原理,它是可以接受的。
您可以使用===
来比较子项,但是如果您需要执行昂贵的计算或在props.children不同时重新渲染很多子项,您可以在父项中记住子项,因此除非有子项,否则您不会这样做实际上真的改变了:
function App() {
const [children, setChildren] = React.useState([
{ id: 0, name: 'one' },
{ id: 1, name: 'two' },
]);
const [, setUnRelated] = React.useState({});
const addChild = () =>
setChildren(children =>
children.concat({
id: children.length,
name: 'new child',
})
);
const Children = React.useMemo(
() => children.map(c => <Child key={c.id} {...c} />),
[children]
);
console.log('parent rendering');
return (
<div>
<button onClick={addChild}>Add child</button>
<button onClick={() => setUnRelated({})}>
Unrelated change
</button>
<ChildList>{Children}</ChildList>
</div>
);
}
class ChildList extends React.PureComponent {
componentDidUpdate(prevProps) {
if (prevProps.children !== this.props.children) {
console.log('Children in child list not equal');
}
}
render() {
return this.props.children;
}
}
const Child = React.memo(function Child({ id, name }) {
const rendered = React.useRef(0);
rendered.current++;
return (
<div>
Rendered {rendered.current} times for: {name} id: {id}
</div>
);
});
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>