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

IT技术 reactjs react-context
2021-05-19 20:37:26

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

  1. 使用 Provider 提供的值的 contextType 和 Consumer 方法有什么区别?在什么情况下我们应该使用哪种方法?
  2. Provider 在基于类的组件中公开的值是否可以被使用 useContext 的 React 钩子组件使用?我有相同的设置,我最终将 useContext 转换为 Context.Consumer。
  3. 我有一个非常简单的设置,其中我有一个基于 Provider Class 的组件,它暴露了一些状态值。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>
    );
  }
}

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>
    );
  }
}

应用程序.js

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

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

ReactDOM.render(output, document.getElementById("root"));
2个回答

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

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

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

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

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

编辑表单值

  1. 静态 contextType 和 class.contextType
  2. 使用上下文
  3. 上下文.消费者

几乎相同,它们之间的区别在于(1)在类组件中使用,useContext是一个钩子,最好的是我们可以在一个功能组件中多次使用这个钩子。(3)只能在jsx或在render(return).(1) 和(2) 可以在 return 之外使用。