React Context 中的函数和重新渲染

Posted

技术标签:

【中文标题】React Context 中的函数和重新渲染【英文标题】:Functions and re-renders in React Context 【发布时间】:2019-03-05 11:03:31 【问题描述】:

我对新的 React Context-api 有两个问题:

    React 文档有以下示例Updating context from a nested component。在构造函数中声明 toggleTheme 函数(而不是作为类方法)是否有某些特定原因?

import ThemeContext, themes from './theme-context';
import ThemeTogglerButton from './theme-toggler-button';

class App extends React.Component 
  constructor(props) 
    super(props);

    this.toggleTheme = () => 
      this.setState(state => (
        theme:
          state.theme === themes.dark
            ? themes.light
            : themes.dark,
      ));
    ;

    // State also contains the updater function so it will
    // be passed down into the context provider
    this.state = 
      theme: themes.light,
      toggleTheme: this.toggleTheme,
    ;
  

  render() 
    // The entire state is passed to the provider
    return (
      <ThemeContext.Provider value=this.state>
        <Content />
      </ThemeContext.Provider>
    );
  


function Content() 
  return (
    <div>
      <ThemeTogglerButton />
    </div>
  );


ReactDOM.render(<App />, document.root);
    在许多示例中,Provider-component 的值是 high-up-component 的状态(就像上面的示例一样)。这意味着每次我想更新 Context-value 时,我都需要更新 high-up 组件的状态。这意味着 high-up 组件在状态更新时重新渲染,这反过来意味着它的所有子组件也重新渲染。但我想要的只是让消费者组件监听该提供者组件重新渲染。现在,每次我更新 Context-value 时,基本上整个应用程序都会重新渲染......我错过了什么吗?

【问题讨论】:

【参考方案1】:

toggleTheme 作为回调传递,应该绑定到正确的this。如果是类原型方法,则无论如何都需要在构造函数中使用this.toggleTheme = this.toggleTheme.bind(this)。见this related question。

正如the documentation 所说,

只要 Provider 的 value 属性发生变化,所有作为 Provider 后代的 Consumer 都会重新渲染。从 Provider 到其后代 Consumer 的传播不受 shouldComponentUpdate 方法的约束,因此即使祖先组件退出更新,Consumer 也会更新。

应重新渲染包含 Provider (App) 的组件以提供新的 value,而其后代则不应。在此示例中,其直接子代 (Content) 可以是 PureComponent,以防止在整个层次结构中进行不必要的重新渲染。对于影响整个应用程序的上下文(如主题上下文),不会有显着的性能改进。

【讨论】:

有道理...感谢您的解释!

以上是关于React Context 中的函数和重新渲染的主要内容,如果未能解决你的问题,请参考以下文章

React Context API 似乎要重新渲染每个组件

React Context API似乎重新渲染每个组件

React Context API 并避免重新渲染

新的 React Context API 会触发重新渲染吗?

React (Native) Context API 导致 Stack Navigator (React Navigation 5) 在状态更新后重新渲染

React Context 不适用于服务器端渲染