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

问题描述 投票:9回答:1

我一直在尝试理解新的React Context API并且正在玩它。我只是想检查一个简单的案例 - 当更新数据到提供者时,所有重新呈现的内容。

检查this small example on Codesandbox

所以,在我的例子中,我有一个App组件 - 具有类似这样的状态 -

this.state = {
  number - A random number
  text - A static text
} 

我从这里创建一个新的React Context包含来自state的numbertext,并将值传递给两个消费者NumberText

所以我的假设是如果随机数更新,它将改变上下文,并且两个组件都应该触发重新渲染。

但实际上,价值正在更新,但没有重新发生。

所以,我的问题 -

  1. 对上下文的更新是否不通过通常的重新渲染传播?因为当上下文改变时我看不到我的日志/颜色变化。
  2. 是否更新了该提供商的所有消费者?
javascript reactjs react-context
1个回答
10
投票

对上下文的更新是否不通过通常的重新渲染传播?因为当上下文改变时我看不到我的日志/颜色变化。

对上下文值的更新不会触发提供程序的所有子项的重新呈现,而只触发从Consumer中呈现的组件,因此在您的情况下,虽然数字组件包含Consumer,但不会重新呈现Number组件而不仅仅是Consumer中的render函数,因此值更改了上下文更新。这样它的性能非常高,因为它不会触发所有子节点的重新渲染。

是否更新了该提供商的所有消费者?

该提供商的所有消费者都将经历更新周期,但他们是否重新呈现是由反应虚拟DOM比较决定的。你可以在控制台中看到这个sandbox的演示

编辑

您需要确保的是,组件是作为ContextProvider组件的子项呈现的,并且您将处理程序传递给它而不是将它们呈现为内联并更新ContextProvider的状态,因为这将触发重新呈现内部的所有组件ContextProvider

执行使用

App.js

  render() {
    return (
      <AppContext.Provider
        value={{ ...this.state, updateNumber: this.updateNumber }}
      >
        {this.props.children}
      </AppContext.Provider>
    );
  }

index.js

class Data extends React.Component {
  render() {
    return (
      <div>
        <h1>Welcome to React</h1>
        <Number />
        <Text />
        <TestComp />
        <AppContext.Consumer>
          {({ updateNumber }) => (
            <button onClick={updateNumber}>Change Number </button>
          )}
        </AppContext.Consumer>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(
  <App>
    <Data />
  </App>,
  rootElement
);

性能较低的用法

App.js

class App extends Component {
  constructor() {
    super();
    this.state = {
      number: Math.random() * 100,
      text: "testing context api"
    };
  }

  updateNumber = () => {
    const randomNumber = Math.random() * 100;
    this.setState({ number: randomNumber });
  };

  render() {
    return (
      <AppContext.Provider value={this.state}>
        <div>
          <h1>Welcome to React</h1>
          <Number />
          <Text />
          <TestComp />
          <button onClick={this.updateNumber}>Change Number </button>
        </div>
      </AppContext.Provider>
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.