我正在测试React的Context API,并且已经成功地将我的状态项和方法传递给了Consumer组件。但是,当我在方法中添加一些条件逻辑时,将丢失对状态对象项的引用。我收到“无法读取未定义的属性'颜色'”错误。如何通过该状态对象中的颜色键进行引用,以便运行逻辑?我可以在Provider组件中执行此操作,还是只能在Consumer组件中执行此逻辑?
提供商容器文件-ProviderComp.js
class ProviderComp extends Component{
state={
name: "Gary",
age: 20,
color: "Red",
changeMind: function(){
if(this.color === "Red"){
document.getElementById("root").style.background="blue";
document.getElementById("root").style.color="white";
this.setState({
name: "Tony",
age: 35,
color: "Blue"
})
}
if(this.color === "Blue"){
document.getElementById("root").style.background="red";
document.getElementById("root").style.color="black";
this.setState({
name: "Gary",
age: 20,
color: "Red"
})
}
}
}
render(){
return(
<UserInfo.Provider value={{state:this.state}}>
{this.props.children}
</UserInfo.Provider>
)
}
}
export default ProviderComp;
消费者组件-ConsumerComp.js
import React, {Component} from "react";
import UserInfo from "./ContextData";
class ConsumerComp extends Component{
render(){
return(
<UserInfo.Consumer>
{(context)=>(
<React.Fragment>
<p>My Name Is: {context.state.name}</p>
<p>My Age Is: {context.state.age}</p>
<p>My Favorite Color Is: {context.state.color}</p>
<button onClick={context.state.changeMind}>Changed My Mind</button>
</React.Fragment>
)}
</UserInfo.Consumer>
)
}
}
export default ConsumerComp;
答案 0 :(得分:0)
我认为您的方法容易出错。
当您在状态外部创建函数,然后作为道具传递给ConsumerComp
时,效果会更好:
class ProviderComp extends Component{
state={
name: "Gary",
age: 20,
color: "Red"}
constructor(props){
super(props);
this.changeMind=this.changeMind.bind.this;
}
changeMind(){
if(this.state.color === "Red"){
// ...///
this.setState({
//...
})
}
}
///
render(){
<UserInfo.Provider value={{state:this.state}}>
{React.Children.map(children, (child, index) =>
React.cloneElement(child,{changeMind: this.changeMind})
)}
</UserInfo.Provider>
}
}
答案 1 :(得分:0)
谢谢克里斯。问题出在ES5语法上。我需要使用粗箭头语法=>将此绑定到组件。这使我可以按照逻辑访问状态。这是工作代码。请注意,通过此过程,上下文API允许人们跳过多个级别的道具发送,这非常酷。
import React, {Component} from "react";
import UserInfo from "./ContextData";
class ProviderComp extends Component{
state={
name: "Gary",
age: 20,
color: "Red",
changeMind: ()=>{
if(this.state.color === "Red"){
document.getElementById("root").style.background="blue";
document.getElementById("root").style.color="white";
this.setState({
name: "Tony",
age: 35,
color: "Blue"
})
}
if(this.state.color === "Blue"){
document.getElementById("root").style.background="red";
document.getElementById("root").style.color="black";
this.setState({
name: "Gary",
age: 20,
color: "Red"
})
}
}
}
render(){
return(
<UserInfo.Provider value={{state:this.state}}>
{this.props.children}
</UserInfo.Provider>
)
}
}
export default ProviderComp;