Class.contextType 和 Context.Consumer 之间的区别与工作示例
Posted
技术标签:
【中文标题】Class.contextType 和 Context.Consumer 之间的区别与工作示例【英文标题】:Difference Between Class.contextType and Context.Consumer with working example 【发布时间】:2020-10-09 08:59:04 【问题描述】:我正在尝试了解 React 上下文 API,并且正在阅读官方文档。如果有人能对以下几点提出更多说明,我将不胜感激,因为官方文档没有明确说明。
-
contextType 和 Consumer 方法有什么区别
使用 Provider 提供的值?在什么情况下我们应该
使用哪种方法?
Provider 在基于类的组件中公开的值可以是
由使用 useContext 的反应钩子组件使用?我有同样的
设置,我最终将 useContext 转换为 Context.Consumer。
我有一个非常简单的设置,其中我有一个提供者类
基于暴露一些状态值的组件。提供者
只有一个子组件,它也是一个消费者。当我使用
Context.Consumer 在孩子中获取值,一切
按预期工作。但是当我在孩子们中使用 contextType
组件,我看到一个空对象。
ContextProvider.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>
);
App.js
import ContextProvider from "../../playground/ContextProvider";
const output = (
<Provider store=reduxStore>
<ContextProvider />
</Provider>
);
ReactDOM.render(output, document.getElementById("root"));
【问题讨论】:
我认为您使用的是 v16.3.0 - v16.6.0 之间的 react 版本。 contextType 支持是在 16.6.0 中引入的。请查看此帖子***.com/questions/49870098/… 是的,我目前在 16.13.1。但是上下文页面上没有与版本支持相关的信息reactjs.org/docs/context.html @ryna,文档显示了最新版本的API,具体API介绍需要查看发行说明::reactjs.org/blog/2018/10/23/react-v-16-6.html 【参考方案1】:contextType和Consumer方法消费Provider提供的值有什么区别?在什么情况下我们应该使用哪种方法?
static contextType
赋值是在 v16.6.0 中引入的,作为在渲染方法之外使用上下文的一种方式。 Consumer 和静态上下文之间的唯一区别是使用 contextType 允许您在渲染方法之外使用上下文
Provider在基于类的组件中暴露的值是否可以被使用useContext的react hook组件使用?
是的,来自 Provider 的上下文值也可以被 useContext
使用。但是,您只能在功能组件而不是类组件中使用 useContext
,并且在 v16.8.0 或支持钩子的 react 之后也可以使用
P.S.您必须确保通过在消费者组件中导入提供程序不会导致循环依赖,反之亦然
【讨论】:
我还参考了一篇在线文章,它说使用消费者是一种使用提供者值的传统和遗留方式。真的吗?如果是这种情况,我们是否只使用 contextType 但根据您的回复,我会不这么认为。 taniarascia.com/using-context-api-in-react。 “检索 Context 值的传统方法是将子组件包装在 Consumer 中。从那里,您可以将 value 属性作为 props 访问。您可能仍然会看到这一点,但它更像是访问 Context 的传统方式。 " @ryan 上下文 api 已多次更改。最初我们需要定义 contextType,但也需要为我们使用 childContextTypes 的提供者。然后在 v16.3 中,react 引入了提供者消费者 api,它变得流行且简单,但有一个缺点是使用自定义来使用渲染函数之外的上下文,因此在 v16.6.0 中他们对其进行了改进并添加了静态 contextType 支持,以便我们可以在其他生命周期中也使用 contextType。然后随着钩子的出现,他们引入了 useContext 来在功能组件中使用上下文。 因此,虽然 contextType 是传统方式,但它也是使用上下文的最新方式。 我进行了更改并已将 componentDidMount 中的“console.log(this.context)”从渲染中移出,但我仍然看到这些值未定义。我在这里错过了什么? 可能是循环依赖。在单独的文件中而不是在提供者中创建上下文【参考方案2】:-
静态 contextType 和 class.contextType
使用上下文
context.Consumer
几乎相同,它们之间的区别在于(1)用于类组件和 useContext 是一个钩子,最好的是我们可以在一个功能组件中多次使用这个钩子。(3) 只能在 jsx 或 render(return) 中使用。(1) 和(2) 可以在 return 之外使用。
【讨论】:
以上是关于Class.contextType 和 Context.Consumer 之间的区别与工作示例的主要内容,如果未能解决你的问题,请参考以下文章
sh Findhttp://www.cyberciti.biz/faq/unix-linux-finding-files-by-content/
sh Findhttp://www.cyberciti.biz/faq/unix-linux-finding-files-by-content/
spring配置问题:严重: Error configuring application listener of class org.springframework.web.context.Conte
iOSCGContextSaveGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTE(代
在 Spring+Tomcat 上使用 JSF 2.2.9 会导致 java.lang.NoClassDefFoundError: javax/enterprise/context/spi/Conte
AAPT: error: resource drawable/soil_backgroud_content3 (aka cn.bloghut:drawable/soil_backgroud_conte