【问题标题】:Avoid unneccessary re-rendering in React dynamic nested components避免在 React 动态嵌套组件中进行不必要的重新渲染
【发布时间】:2021-01-14 23:01:55
【问题描述】:

我的项目的状态包括嵌套动物的列表,例如:

    {"europe":{"air":{name:"warbler", points:0}}}

我的组件是根据这些数据生成的,在最低级别(动物本身),有一个按钮当前正在触发一系列回调到最高级别,开始向 reducer 调度。每次单击按钮时,来自每个大陆的所有组件都会重新渲染。 即使每个级别的组件都需要来自状态对象的一些数据,实现 useContext 会更好吗? 我尝试实现 useCallback,以防止重新渲染,但我不知道是哪些回调导致了它。优化渲染一系列嵌套组件(没有 redux)的最佳方法是什么?

App组件内部

 {Object.entries(state.animalData).map(([continent, areas]) => (
                    <Continent
                        key={continent}
                        areas={areas}
                        totals={state.totals.continents[continent]}
                        handleVote={(
                            num: number,
                            animal: string,
                            area: string
                        ) => triggerChange(num, animal, area, continent)}
                    />
                ))}

大陆组件内部

               <Area
                    key={area}
                    area={area}
                    animals={animals}
                    onVote={(num: number, animal: string) =>
                        handleVote(num, animal, area)
                    }
                  />

区域组件内部

    {animals.map(animal => (
                <Animal
                    key={animal.name}
                    animal={animal}
                    voted={(num: number) => onVote(num, animal.name)}
                />
            ))}

动物组件内

          <div>
            <h4>{animal.name}</h4>
            <div>
                <button onClick={voted(+1)}> Upvote </button>
                <button onClick={voted(-1)}> Downvote </button>
            </div>
            <h4>{`${animal.points} Points`}</h4>
            <hr />
          </div>

【问题讨论】:

    标签: reactjs typescript performance react-hooks react-functional-component


    【解决方案1】:

    您的组件会触发重新渲染,因为您在任何地方都使用内联定义的函数,而这些函数在引用上不稳定。您可以使用useCallback (https://reactjs.org/docs/hooks-reference.html#usecallback) 挂钩来防止重新渲染。

    但您也可以使用包含voted 回调的上下文提供程序(如您所建议的)。这样您就不必使用道具钻孔来将功能获取到需要它的组件。

    这里详细解释了这个的基本解决方案:https://medium.com/@jeromefranco/how-to-avoid-prop-drilling-in-react-7e3a9f3c8674

    【讨论】:

    • 非常感谢您的帮助!那么将这里创建的所有内联函数包装在useCallback中会是一个好主意吗,我无法弄清楚我是否只需要包装最低级别的函数,或者最高级别的函数以防止从孩子开始重新渲染触发链,但先渲染父函数。
    • 那将是最高级别的功能。然后,您只需将其作为道具值传递。
    • 由于最高级别的函数接受参数我将如何得到这个,我添加了 const triggerChange = React.useCallback(( num: number, animal: string, area: string,continent: string ) => { dispatch({ type: 'vote', payload: { num, animal, area,continent, }, }); },[]);但它似乎仍然重新渲染,有什么想法吗?再次感谢这个
    • 重新渲染的究竟是什么?你能通过codepen oder codesandbox提供一个工作示例吗?我们不知道您代码中的所有逻辑流程,因此很难说问题出在哪里。
    猜你喜欢
    • 2021-12-25
    • 1970-01-01
    • 2020-01-10
    • 2020-05-04
    • 1970-01-01
    • 2020-07-26
    • 1970-01-01
    • 2020-12-13
    • 2020-05-04
    相关资源
    最近更新 更多