Class.contextType 和 Context.Consumer 之间的区别与工作示例

rya*_*yan 3 reactjs react-context

我正在尝试了解 React 上下文 API,并且正在阅读官方文档。如果有人可以对以下几点进行更多说明,我将不胜感激,因为官方文档没有明确说明。

  1. 使用 Provider 提供的值的 contextType 和 Consumer 方法有什么区别?在什么情况下我们应该使用哪种方法?
  2. Provider 在基于类的组件中公开的值是否可以由使用 useContext 的 React 钩子组件使用?我有相同的设置,我最终将 useContext 转换为 Context.Consumer。
  3. 我有一个非常简单的设置,其中我有一个基于 Provider 类的组件,它暴露了一些状态值。Provider 只有一个子组件,它也是消费者。当我在孩子中使用 Context.Consumer 来获取值时,一切都按预期工作。但是当我在子组件中使用 contextType 时,我看到一个空对象。

上下文提供者.js

import React from "react";
import {ContextConsumer} from "./ContextConsumer";
export const TestContext = React.createContext({
    count: 1,
    incrCount: (count)=>{
     console.log(`count value :- ${count}`)
     }
});

export class ContextProvider extends React.Component {
  incrCount = () => {
    this.setState({
      count: this.state.count + 1,
    });
  };

  state = {
    count: 5,
    incrCount: this.incrCount,
  };

  render() {
    return (
      <TestContext.Provider value={this.state}>
        <ContextConsumer />
      </TestContext.Provider>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

ContextConsumer.js

import React from "react";
import { TestContext } from "./ContextProvider";

export class ContextConsumer extends React.Component {
    static contextType=TestContext

  componentDidMount() {
        const {count,incrCount}= this.context;
        console.log(`count:- ${(count)}`)
        console.log(`incrCount:- ${incrCount}`)
    }
  render() {


    return (
      <div>


        **// BELOW CODE IS WORKING AS EXPECTED**
        <TestContext.Consumer>
          {({ count, incrCount }) => (
            <button onClick={incrCount}>Count is {count}</button>
          )}
        </TestContext.Consumer>
      </div>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

应用程序.js

import {ContextProvider}  from "../../playground/ContextProvider";

const output = (
  <Provider store={reduxStore}>
    <ContextProvider />
  </Provider>
);

ReactDOM.render(output, document.getElementById("root"));
Run Code Online (Sandbox Code Playgroud)

Shu*_*tri 6

使用 Provider 提供的值的 contextType 和 Consumer 方法有什么区别?在什么情况下我们应该使用哪种方法?

static contextType分配在v16.6.0引入了一种利用渲染方法的范畴之外。消费者和静态上下文之间的唯一区别是,使用 contextType 也允许您在渲染方法之外使用上下文

Provider 在基于类的组件中公开的值是否可以由使用 useContext 的 React 钩子组件使用?

是的,来自 Provider 的上下文值也可以被使用useContext。但是,您只能useContext在功能组件内部使用,而不能在类组件中使用,并且在 v16.8.0 或支持钩子的 react 之后

PS您必须确保通过在消费者组件中导入提供者以及其他方式不会导致循环依赖的一件事

编辑表单值

  • @ryan 上下文 api 已更改多次。最初我们需要定义 contextType,但对于提供者,我们将使用 childContextTypes。然后在 v16.3 中,React 引入了提供者消费者 api,它变得流行且简单,但有一个缺点,即使用自定义在渲染函数之外使用上下文,因此在 v16.6.0 中,他们对其进行了改进并添加了静态 contextType 支持,以便我们可以在其他生命周期中也使用 contextType。然后,随着钩子的出现,他们引入了 useContext 来使用功能组件中的上下文。 (2认同)