React - re-render 只有一个 child 组件的优雅方式?

React - elegant way to re-render just one child component?

我正在开发 table 组件。当我在 <tbody /> 上左右滚动时,我希望它只更新 <theader /> 的 xOffset,它位于一个单独的组件中,我将调用 <Header Component />。结构如下:

<Parent Component >
    <Header Component />
    <Very Expensive Body divs/>
    <Very Expensive Body divs/>
    <Very Expensive Body divs/>
</Parent Component >

滚动侦听器在 parent 组件上,xOffset 是 Parent 组件状态的一部分。当我左右滚动时,它也 re-renders re-render body 非常昂贵的组件。

对于 re-render 的 Header 组件,我有哪些选择?

1) 使用 Redux 和选择器。 Parent 组件将 xOffset 分派到应用程序状态,而 <Header Component /> 仅在选择器上侦听它。好像矫枉过正了...

2) 我将所有 <Very Expensive Body Comp divs > 分解成它们自己的组件,并使用 ShouldComponentUpdate,这样它就不会 re-render 如果除 xOffset 之外的一切都保持不变。这看起来并不过分,但我觉得我将要处理同样的问题,因为我必须将滚动侦听器放在这个新组件上......然后使用 parent 组件作为中介..oof。

还有第三种更优雅的方案吗?

我希望有一种方法可以将函数传递给 <Header Component />,这样当 parent 组件左右滚动时,它会使用该函数来更新 <Header Component /> 这将导致它变为 re-render。

如果我理解正确,一种选择是执行以下操作:

<Parent Component >
    <Header Component />
    { this.getVeryExpensiveBodyDivs() }
</Parent Component >

并让 getVeryExpensiveBodyDivs 第一次生成并缓存 div,然后如果它们在缓存中,则仅从缓存中访问它们。缓存只是一个实例变量 (this.cachedVeryExpensiveBodyDivs).

然后,在您的 table 组件的 componentWillReceiveProps 中,您可以检查是否有任何应该影响非常昂贵的主体 div 的道具发生变化。如果道具更改会影响非常昂贵的主体 div,请清除缓存。下次调用 getVeryExpensiveBodyDivs 时,它将重新生成并重新缓存 div。

选项2!将非常昂贵的 div 标签分解成它们自己的组件并使用 shouldComponentUpdate。将所有元素保留在一个 render() 函数中并不能像您开始看到的那样很好地扩展。使用 React 的全部好处是您可以创建简单、可重用的组件并使用这些组件构建更复杂的 UI。您似乎打算将所有内容都保留在一个组件中,但这实际上是 React 中的 anti-pattern。

但是,不要向每个组件添加新的滚动侦听器。相反,只需像您正在做的那样将它保留在 parent 组件上,并将滚动值作为道具传递给所有新组件。如果它们只需要在滚动一定数量的屏幕后更改,您可以在每个 child 的 shouldComponentUpdate 函数中更新它。