仅当子组件在componentDidUpdate中不同时才执行

问题描述 投票:0回答:2

我需要比较prevProps的子代和当前props的子代,并且仅在componentDidUpdate方法中的代码不同时才执行代码。

当孩子是对象数组时,我如何比较他们?

componentDidUpdate(prevProps) {
  if(!_.isEqual(prevProps.children, this.props.children)) {
   console.log('not equal');
   // execute some code
}
javascript arrays reactjs children react-props
2个回答
0
投票

您可以简单地使用常规的等于运算符:

componentDidUpdate(prevProps) {
    if (prevProps.children !== this.props.children) {
        console.log('not equal');
    }
}

这就是反应文档所说的。但是请注意,这只会检查数组是否不同。它不会检测数组中的对象是否已更改,但是由于react的工作原理,它是可以接受的。


0
投票

您可以使用===来比较子项,但是如果您需要执行昂贵的计算或在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>
© www.soinside.com 2019 - 2024. All rights reserved.