выполнить только если дочерние элементы различаются в componentDidUpdate - PullRequest
0 голосов
/ 30 октября 2019

Мне нужно сравнить дочерние элементы prevProps и текущие реквизиты и выполнять код, только если они отличаются в методе componentDidUpdate.

Как я могу сравнить дочерние элементы, когда они являются массивами объектов?

componentDidUpdate(prevProps) {
  if(!_.isEqual(prevProps.children, this.props.children)) {
   console.log('not equal');
   // execute some code
}

Ответы [ 2 ]

0 голосов
/ 30 октября 2019

Вы можете использовать === для сравнения дочерних элементов, но если вам нужно выполнить дорогостоящие вычисления или вызвать многократный рендеринг, когда 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>
0 голосов
/ 30 октября 2019

Вы можете просто использовать обычный оператор равенства следующим образом:

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

Это то, что говорит документация реагирования. Однако обратите внимание, что это будет только проверять, если массив отличается. Он не будет определять, был ли изменен объект внутри массива, но из-за того, как работает реакция, это приемлемо.

...