简体   繁体   English

通过修改父 State 防止重新渲染

[英]Prevent Re-Render With Modifications to Parent State

How can one modify state in a parent component, and pass it down as props to the children, but only re-render those children when the modified state changes?如何在父组件中修改 state 并将其作为道具传递给子组件,但仅在修改后的 state 更改时重新渲染这些子组件?

My basic setup currently works, but it's causing some unnecessary re-renders.我的基本设置目前有效,但它会导致一些不必要的重新渲染。 The parent components gets information from the URL (using react-router hooks) and modifies it, and then passes that down as props to its children.父组件从 URL(使用 react-router 挂钩)获取信息并对其进行修改,然后将其作为道具传递给其子组件。 The component looks like this:该组件如下所示:

 const myComponent = () => {

    const { dataType } = useParams();
    const { search } = useLocation();

    /// These functions help me transform that data into something more manageable
    const y = queryString.parse(search).collection;
    const { collections, gqlQuery } = getCollections(dataType);
    const collection = collections.find(x => x.value === y);

    return (
     <MyChild collection={collection} /> ... This component is re-rendering unnecessarily.
    )



};

How can I ensure that when the URL doesn't change (the dataType and search values that are pulled using react-router) the child components that receive derived data ALSO won't unnecessarily re-render?如何确保当 URL 不更改(使用 react-router 提取的dataTypesearch值)时,接收派生数据的子组件也不会不必要地重新渲染?

The first step would be to make sure that the reference to collection variable changes only when one of the dependencies change:第一步是确保仅当其中一个依赖项发生更改时,对collection变量的引用才会更改:

useMemo(() => {
  const y = queryString.parse(search).collection;
  const { collections, gqlQuery } = getCollections(dataType);
  const collection = collections.find(x => x.value === y);
}, [search, dataType]);

The second would be to make sure that the component only re-renders when it receives new props:第二个是确保组件仅在收到新道具时重新渲染:

import { memo } from 'react';

function Child() {

}

export default memo(Child);

You can also use the second argument for memo to customise what is compared.您还可以使用memo的第二个参数来自定义比较的内容。

function Child(props) {

}
function areEqual(prevProps, nextProps) {
  /*
  return true if passing nextProps to render would return
  the same result as passing prevProps to render,
  otherwise return false
  */
}
export default React.memo(Child, areEqual);

React.memo - Docs React.useMemo - Docs React.memo - 文档React.useMemo - 文档

PS: Note that React is usually super fast with re-renders. PS:请注意,React 通常在重新渲染时非常快。 Use these only as a performance enhancement after measuring their impact.仅在衡量其影响后将其用作性能增强。 There is a chance it has worse performance than before有可能它的性能比以前更差

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM