React Context API - Как получить ссылку на объект состояния в поставщике для условного метода

Я тестирую контекстный API React и успешно передал свои элементы состояния и метод компоненту потребителя. Однако, когда я добавляю некоторую условную логику в метод, я теряю ссылку на элементы объекта состояния. Я получаю сообщение об ошибке "Не удается прочитать свойство" цвет "неопределенного". Как мне ссылаться на цветовой ключ в этом объекте состояния, чтобы я мог запустить логику? Могу ли я сделать это в компоненте "Провайдер" или я могу использовать эту логику только в компоненте "Потребитель"?

Файл контейнера провайдера - 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 ответа

Спасибо, Крис. Проблема в синтаксисе 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;

Я думаю, что ваш подход подвержен ошибкам. лучше, когда вы создаете функцию вне состояния, а затем переходите к 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>
}

}

Другие вопросы по тегам