React Context API-如何为条件方法在提供程序中获取对状态对象的引用

时间:2018-07-23 14:03:50

标签: javascript reactjs react-context

我正在测试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;

2 个答案:

答案 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;