【问题标题】:React Context API - How to Get Reference To State Object In Provider For A Conditional MethodReact Context API - 如何在条件方法的提供者中获取对状态对象的引用
【发布时间】:2018-07-23 14:03:50
【问题描述】:

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

【问题讨论】:

  • 你试过把它改成箭头函数吗?喜欢changeMind: () =&gt; {
  • 你是对的,使用 => 语法绑定 this,它允许我引用状态。我将发布工作代码。

标签: javascript reactjs react-context


【解决方案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;

【讨论】:

    【解决方案2】:

    我认为您的方法容易出错。 当您在状态外创建函数时更好,然后作为道具传递给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>
    }
    

    }

    【讨论】:

    • 谢谢。我真的在尝试使用新的 Context API 来测试在没有道具的情况下传递长方法的能力,以避免在我有多个图层的情况下进行道具钻探。这似乎是一种有趣的方法。
    猜你喜欢
    • 2019-02-06
    • 2020-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-21
    • 1970-01-01
    相关资源
    最近更新 更多