避免在React动态嵌套组件中不必要的重新渲染

时间:2020-09-29 10:33:28

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

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

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

我的组件是基于此数据生成的,并且在最低级别(动物本身)上,有一个按钮当前正在触发一系列回调到最高级别,从而开始调度到reducer。每次单击按钮时,每个大陆的所有组件都会重新渲染。 即使组件的每个级别都需要状态对象提供一定数量的数据,实现useContext都会更好吗? 我试图实现useCallback,以防止重新呈现,但我不知道是哪个回调引起的。优化呈现一系列嵌套组件(不使用redux)的最佳方法是什么?

应用组件内部

 {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>

1 个答案:

答案 0 :(得分:0)

您的组件会触发重新渲染,因为您到处都使用内联定义的函数,而这些函数并不是参照稳定的。您可以使用useCallbackhttps://reactjs.org/docs/hooks-reference.html#usecallback)挂钩来防止重新渲染。

但是您也可以使用上下文提供者(如您建议的那样)来保存voted回调。这样一来,您无需使用prop钻孔就可以将功能传递到需要它的组件。

对此的基本解决方案在此处详细说明:https://medium.com/@jeromefranco/how-to-avoid-prop-drilling-in-react-7e3a9f3c8674