reactjs React上下文API速度慢

evrscar2  于 2022-12-26  发布在  React
关注(0)|答案(3)|浏览(138)

我正在试验新的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用户界面),大约有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会重新呈现?它没有使用呈现函数中的任何上下文属性。我希望只有页脚组件会在每次上下文更改时重新呈现

5cnsuln7

5cnsuln71#

注意事项因为context使用引用标识来决定何时重新呈现,所以当提供者的父提供者重新呈现时,有一些陷阱可能会触发消费者中的无意呈现。例如,下面的代码将在每次提供者重新呈现时重新呈现所有消费者,因为总是为value创建一个新对象:

class App extends React.Component {
  render() {
    return (
      <Provider value={{something: 'something'}}>
        <Toolbar />
      </Provider>
    );
  }
}

要解决此问题,请将值提升到父级的状态:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: {something: 'something'},
    };
  }

  render() {
    return (
      <Provider value={this.state.value}>
        <Toolbar />
      </Provider>
    );
  }
}

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

gxwragnw

gxwragnw2#

用useMemo记住你选择的项,以避免在引用同一项时创建一个新的对象,然后在一个专用的上下文中传递它

oxf4rvwz

oxf4rvwz3#

在您的解决方案中,无论何时重新呈现组件,value的新示例都会作为prop传递下来,这也会触发子组件的重新呈现。
如果你使用钩子,为了防止这种情况,记住你想要传递的value对象,在useMemouseCallback钩子中。事实上,这应该作为一个基本的React实践应用于你的任何组件,而不仅仅是一个上下文组件。除非你传递一个原语值(string,number,...),不要直接创建示例或内联函数并将其作为prop传递。请确保您传递的prop在React组件的每个渲染周期后都不会更改。

相关问题