React Context API似乎重新呈现了每个组件

Spe*_*gum 4 javascript reactjs react-context

我试图在我的应用程序中使用新的Context API,并且看起来每次更新上下文时,它都会重新渲染与其连接的任何组件。我有一个沙盒演示设置,可以查看代码和工作问题。当您输入内容时-按钮上下文将呈现,反之亦然。我最初的想法是,如果您输入输入内容,那么只会打印出输入内容。

演示

这是如何运作的还是我错过了什么?谢谢,斯宾塞

Mat*_*ara 7

这是预期的行为。当提供者数据更新时,消费者重新呈现组件。此外,shouldComponentUpdate钩子对消费者不起作用。

\n\n

引用 React 的内容 API:

\n\n
\n

每当 Provider\xe2\x80\x99s value prop 发生变化时,作为 Provider 后代的所有 Consumer 都将重新渲染。从 Provider 到其后代 Consumers 的传播不受 shouldComponentUpdate 方法的约束,因此即使祖先组件退出更新,Consumer 也会更新。

\n
\n\n

欲了解更多信息,请查看此处

\n


ped*_*ern 5

我避免使用react context API重新呈现的方式:

首先,我将组件编写为纯功能组件:

const MyComponent = React.memo(({
    somePropFromContext,
    otherPropFromContext, 
    someRegularPropNotFromContext  
}) => {
    ... // regular component logic
    return(
        ... // regular component return
    )
});
Run Code Online (Sandbox Code Playgroud)

然后,我编写了一个从上下文中选择道具的函数:

function select(){
  const { someSelector, otherSelector } = useContext(MyContext);
  return {
    somePropFromContext: someSelector,
    otherPropFromContext: otherSelector,
  }
}

Run Code Online (Sandbox Code Playgroud)

我有我的连接HOC写道:

function connect(WrappedComponent, select){
  return function(props){
    const selectors = select();
    return <WrappedComponent {...selectors} {...props}/>
  }
}
Run Code Online (Sandbox Code Playgroud)

全部一起

import connect from 'path/to/connect'

const MyComponent ... //previous code

function select() ... //previous code

export default connect(MyComponent, select)
Run Code Online (Sandbox Code Playgroud)

用法

<MyComponent someRegularPropNotFromContext={something} />
Run Code Online (Sandbox Code Playgroud)

演示版

演示在codesandbox上

结论

MyComponent仅在上下文中的props props用新值更新时才会重新渲染,如果值相同,则不会重新渲染。另外,它还避免了根据上下文中未使用的上下文重新渲染任何其他值MyComponent。select中的代码将在每次上下文更新时执行,但由于它没有任何作用,所以可以,因为不会MyComponent浪费任何重新渲染。

  • 佩德罗斯河之战 (3认同)
  • 这不违背了 Context API 应该做的事情吗?不妨使用 Redux,因为您正在创建自己的“连接”功能...添加连接器仍然存在两个问题:Wrapper Hell 和 Props Drilling (2认同)