React Context API 很慢

par*_*ite 2 reactjs office-ui-fabric react-context react-hooks

我正在尝试新的 Context API 和钩子。我创建了一个带有侧边栏(树视图)、页脚和主要内容页面的应用程序。我有一个上下文提供者

const ContextProvider: FunctionComponent = (props) => {

const [selected, setSelected] = useState(undefined);
const [treeNodes, setTreeNodes] = useState([]);

return (
    <MyContext.Provider
        value={{
            actions: {
                setSelected,
                setTreeNodes
            },
            selected,
            treeNodes
        }}
    >
        {props.children}
    </MyContext.Provider>
);
Run Code Online (Sandbox Code Playgroud)

在我的内容组件中,我有一个包含大约 1000 个项目的详细信息列表(Office Fabric UI)。当我单击列表中的项目时,我想在上下文中更新所选项目。这可行,但速度确实很慢。选择列表中的项目大约需要 0.5-1 秒。该列表是虚拟化的。我已经在生产版本中尝试过了。情况好一点,但单击列表时有明显的滞后。页脚正在使用 myContext 来显示有关所选项目的信息。

这是我的组件中的一些代码

const cntx = useContext(MyContext);

const onClick = (item) => {
    cntx.actions.setSelected(item);
};
Run Code Online (Sandbox Code Playgroud)

我使用的上下文错误吗?

我创建了一个示例沙箱来演示。您可以滚动到大约第 100 个索引,然后单击几次以查看它如何变得无响应。

https://codesandbox.io/s/0m4nqxp4m0

这是 Fabric DetailsList 的问题吗?它会重新渲染很多次吗?我相信问题出在“复杂”DatePicker 组件上,但我不明白为什么DetailsList 会被重新渲染?它没有在渲染函数中使用任何上下文属性。我希望只有页脚组件在每次上下文更改时重新渲染

son*_*rio 5

注意事项\n由于上下文使用引用标识来确定何时重新渲染,因此当提供程序\xe2\x80\x99s 父级重新渲染时,存在一些可能会触发消费者无意渲染的问题。例如,每次 Provider 重新渲染时,下面的代码都会重新渲染所有消费者,因为总是为值创建一个新对象:

\n
class App extends React.Component {\n  render() {\n    return (\n      <Provider value={{something: \'something\'}}>\n        <Toolbar />\n      </Provider>\n    );\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

要解决此问题,请将值提升到parent\xe2\x80\x99s 状态:

\n
class App extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      value: {something: \'something\'},\n    };\n  }\n\n  render() {\n    return (\n      <Provider value={this.state.value}>\n        <Toolbar />\n      </Provider>\n    );\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

https://reactjs.org/docs/context.html#caveats

\n