javascript - React Child 组件无法访问上下文 API
问题描述
根据新的上下文 API 文档,子组件可以使用消费者访问/修改上下文,也可以使用动态上下文来做同样的事情,消费者一切正常,但我不想使用消费者方法,请检查下面的例子
import React, { Component, createContext } from 'react';
import { render } from 'react-dom';
const Context = createContext({theme: 'light', changeTheme: ()=>{}});
class ThemedText extends Component{
static contextType = Context;
changeTheme(){
//i want t do some logi specific to this class component then change the context value
this.context.changeTheme('dark');
}
render(){
return <div>The theme color is {this.context.theme} <button onClick={()=>{this.changeTheme()}}>Change</button></div>
}
}
class ThemedTextWithConsumer extends Component{
render(){
return(
<Context.Consumer>
{({theme, changeTheme}) => (
<div>Theme is {theme} (Consumer) <button onClick={()=>{changeTheme('dark')}}>Change</button></div>
)}
</Context.Consumer>
)
}
}
class App extends Component{
constructor(){
this.state = {
theme: 'light',
changeTheme: this.changeTheme.bind(this)
}
}
changeTheme(theme){
this.setState({theme});
}
render(){
return(
<Context.Provider value={this.state}>
<ThemedText/>
<ThemedTextWithConsumer/>
</Context.Provider>
)
}
}
第一个组件ThemeText是我想要使用的,因为我需要执行一些逻辑,然后从上下文中触发 changeTheme 函数
第二个组件ThemedTextWithConsumer工作正常,但据我所知,我只能在渲染函数内部使用上下文中的函数
我怎样才能使第一个组件ThemedText工作?
这是StackBlitz上的一个工作示例
解决方案
您的 StackBlitz 演示中有两个问题。
首先:您正在使用 v16.5.0 进行反应,而新的 Context 更改是在 16.6.0 版本的 React 中推送的。您必须先更新依赖版本
第二:您没有在单击按钮时调用该函数
更新代码:
class ThemedText extends Component{
static contextType = Context;
changeTheme(){
//i want t do some logi specific to this class component then change the context value
this.context.changeTheme('dark');
}
render(){
return <div>The theme color is {this.context.theme}
<button onClick={()=>{
// call the function here
this.changeTheme()
}}
>
Change
</button>
</div>
}
}
如果您正在使用version 16.3.0 to version prior to 16.6.0
,请参阅此答案以了解如何在渲染之外使用上下文。
推荐阅读
- r - 加入两个具有最接近时间戳间隔的数据集
- angular - 如何在 Angular 7 中创建可选的路由器参数
- javascript - 查询包含长度> 0数组的文档的firebase
- hyperledger-fabric - Hyperledger Fabric:恐慌:运行时错误:fabric/peer/common.NewPeerClientForAddress 处的内存地址无效或 nil 指针取消引用
- sql-server - 没有从新存储过程创建的复杂类型,EF 数据库优先
- mysql - 从相关表中一次选择多项选择计数()
- python - 同一图像的 2 个灰度图像有何不同?
- twitter-bootstrap - Bootstrap Accordion 升级后损坏
- python - Python:A类创建B和C类的实例,B和C如何调用A中的函数或相互调用?
- r - 匹配数据框中的数值