我正在尝试新的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>
);
我的内容组件我有一个DetailsList(Office Fabric UI),大约有1000个项目。当我点击列表中的项目时,我想在上下文中更新所选项目。这可行,但它真的很慢。在列表中选择项目大约需要0.5-1秒。该列表已虚拟化。我在生产构建上尝试过它。事情有点好,但点击列表时有明显的滞后。页脚正在使用myContext来显示有关所选项目的信息。
这是我的组件的一些代码
const cntx = useContext(MyContext);
const onClick = (item) => {
cntx.actions.setSelected(item);
};
我使用上下文错了吗?
我已经创建了一个示例沙箱来演示..您可以滚动到大约第100个索引并单击几次以查看它是如何无响应的。
https://codesandbox.io/s/0m4nqxp4m0
这是Fabric DetailsList的问题吗?它有多次回复吗?我相信问题在于“复杂”的DatePicker组件,但我不明白为什么DetailsList会被重新渲染?它没有在渲染函数中使用任何上下文属性。我希望只有Footer组件才能在每次上下文更改时重新呈现
注意事项因为上下文使用引用标识来确定何时重新呈现,所以当提供者的父级重新呈现时,有些问题可能会在消费者中触发无意的呈现。例如,下面的代码将在每次提供者重新呈现时重新呈现所有使用者,因为始终为值创建新对象:
class App extends React.Component {
render() {
return (
<Provider value={{something: 'something'}}>
<Toolbar />
</Provider>
);
}
}
To get around this, lift the value into the parent’s state:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
value: {something: 'something'},
};
}
render() {
return (
<Provider value={this.state.value}>
<Toolbar />
</Provider>
);
}
}