1

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

4

2 回答 2

1

谢谢克里斯。问题在于 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;

于 2018-07-23T16:21:32.363 回答
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>
}

}

于 2018-07-23T14:18:51.130 回答