React Context

848 阅读2分钟

作用

无需为每个组件手动添加props,就能在组建树间进行数据传递的方法。

使用

// Context 可以让我们无须明确地传遍每一个组件,就能将值深入传递进组件树。
// 为当前的 theme 创建一个 context(“light”为默认值)。
const ThemeContext = React.createContext('light');class App extends React.Component {
  render() {
    // 使用一个 Provider 来将当前的 theme 传递给以下的组件树。    
    // 无论多深,任何组件都能读取这个值。   
    // 在这个例子中,我们将 “dark” 作为当前的值传递下去。    
    return (
      <ThemeContext.Provider value="dark">        
          <Toolbar />
      </ThemeContext.Provider>
    );
  }
}

// 中间的组件再也不必指明往下传递 theme 了。
function Toolbar() { 
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

class ThemedButton extends React.Component {
  // 指定 contextType 读取当前的 theme context。  
  // React 会往上找到最近的 theme Provider,然后使用它的值。  
  // 在这个例子中,当前的 theme 值为 “dark”。  
  static contextType = ThemeContext;
  render() {
    return <Button theme={this.context} />;
  }
}

优点

  • 避免属性层层传递

API

React.createContext

const MyContext = React.createContext(defaultValue);

创建一个conText对象。当 React 渲染一个订阅了这个 Context 对象的组件,这个组件会从组件树中离自身最近的那个匹配的 Provider 中读取到当前的 context 值。

Context.Provider

<MyContext.Provider value={/* 某个值 */}>

每个 Context 对象都会返回一个 Provider React 组件,它允许消费组件订阅 context 的变化。

Provider 接收一个 value 属性,传递给消费组件。一个 Provider 可以和多个消费组件有对应关系。多个 Provider 也可以嵌套使用,里层的会覆盖外层的数据。

当 Provider 的 value 值发生变化时,它内部的所有消费组件都会重新渲染。

注意

当 provider 的父组件进行重渲染时,可能会在 consumers 组件中触发意外的渲染。这样会造成不断的重新渲染。 为了防止这种情况,将状态提升到父节点的 state 里。然后传递给下面的组件中去。更改的时候,更改父节点的状态,进行重新渲染。