当前位置 : 主页 > 网页制作 > React >

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

来源:互联网 收集:自由互联 发布时间:2021-06-15
我刚刚开始尝试使用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, setItem] = useState({ name: "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

网友评论