加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

reactjs – 如何在使用React钩子和备忘录时防止子组件重新渲染?

发布时间:2020-12-15 20:12:00 所属栏目:百科 来源:网络整理
导读:我刚刚开始尝试使用React钩子,我想知道如何防止子组件在父级重新渲染时重新渲染.我正在寻找类似于在componentDidUpdate中返回false的东西.我的问题似乎源于我在子组件中调用的click处理程序,以更改父组件中的状态.由于函数是在父组件中创建的,因此在每个父渲
我刚刚开始尝试使用React钩子,我想知道如何防止子组件在父级重新渲染时重新渲染.我正在寻找类似于在componentDidUpdate中返回false的东西.我的问题似乎源于我在子组件中调用的click处理程序,以更改父组件中的状态.由于函数是在父组件中创建的,因此在每个父渲染上创建它,这会触发子组件中的prop更改,然后导致子渲染(我认为).以下是一些示例代码,以帮助说明这种情况.

function Parent() {
    const [item,setItem] = useState({ name: "item",value: 0 });

    const handleChangeItem = () => {
        const newValue = item.value + 1;
        setItem({ ...item,value: newValue });
    };

    return <Child item={item} changeItem={handleChangeItem} />;
}

const Child = React.memo(function Child({ item,changeItem }) {
    function handleClick(){
        changeItem();
    }
    return (
        <div>
            Name: {item.name} Value: {item.value}
            <button onClick={handleClick}>change state in parent</button>
        </div>
    );
});

如何在每次父组件渲染时阻止子组件渲染?父进程中的handleChangeItem应该位于其他地方,以便不在每次渲染时重新创建吗?如果是这样,它如何访问useState返回的item和setItem?

我很快就会做出反应并开始玩钩子所以我可能会错过一些明显的东西.

解决方法

在你的情况下,记住Child是没有意义的,因为如果项目发生变化,孩子必须重新渲染.但是,如果有一个道具不会改变的情况,但是由于重新创建的函数,孩子仍在重新渲染,你将使用 useCallback钩子来记忆每个渲染上的函数.此外,由于您已经记住了处理程序,因此您应该使用回调方法来更新状态,因为处理程序中的项目只会引用最初创建函数时的值.

function Parent() {
  const [item,value: 0 });

  const handleChangeItem = useCallback(() => {
    setItem(prevItem => ({ ...prevItem,value: prevItem.value + 1 }));
  },[]);

  return (
    <>
      Name: {item.name} Value: {item.value}
      <Child changeItem={handleChangeItem} />
    </>
  );
}

const Child = React.memo(function Child({ item,changeItem }) {
  function handleClick() {
    changeItem();
  }
  console.log("child render");
  return (
    <div>
      <button onClick={handleClick}>change state in parent</button>
    </div>
  );
});

Working demo

附: Credit to @danAbramov for the direction

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读