通过修改父状态防止重新渲染

时间:2020-05-01 19:59:51

标签: javascript reactjs react-router react-hooks

如何修改父组件中的状态,并将其作为道具传递给子级,而仅当修改后的状态更改时才重新渲染这些子级?

我的基本设置目前可以使用,但是会导致一些不必要的重新渲染。父组件从URL获取信息(使用react-router钩子)并对其进行修改,然后将其作为道具传递给其子代。该组件如下所示:

handleSubmit(event) {
    const { email, password} = this.state;

    axios
      .post(
        "http://localhost:4000/users/login",
        {         
            email: email,
            password: password        
        }
      )
      .then(response => {
        if (response.status ===200) {
          this.props.handleSuccessfulAuth(response.data);          
        }
      })
      .catch(error => {
        this.setState({loginErrors:error}) 
      });
    event.preventDefault();
  }


return(<div>{this.state.state.loginError}</div>)

如何确保在URL不变时(使用react-router提取的 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. ) }; dataType值)接收派生数据的子组件也不会不必要地重新-渲染?

1 个答案:

答案 0 :(得分:1)

第一步是确保仅当其中一个依赖项更改时,对collection变量的引用才会更改:

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

第二个是确保组件仅在收到新道具时才重新渲染:

import { memo } from 'react';

function Child() {

}

export default memo(Child);

您还可以将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

PS:请注意,React通常具有重新渲染的超级快。在测量它们的影响之后,仅将它们用作性能增强。它可能有worse performance than before