首页 > 解决方案 > 如何从消费者更新提供者中的上下文值?

问题描述

MyContext.js

import React from "react";

const MyContext = React.createContext('test');
export default MyContext;

我在一个单独的js文件中创建了我的上下文,我可以在其中访问我的父组件以及我的子组件

父.js

import MyContext from "./MyContext.js";
import Child from "./Child.js";

class Parent extends Component {

    constructor(props) {
      super(props);
      this.state = {
        Message: "Welcome React",
        ReturnMessage:""
      };
    }
    
    render() {
        return (
           <MyContext.Provider value={{state: this.state}}>      
              <Child /> 
           </MyContext.Provider>
       )
    }
}

所以我用提供者上下文创建了父组件并在提供者选项卡中调用子组件

Child.js

import MyContext from "./MyContext.js";

class Child extends Component {

    constructor(props) {
      super(props);
      this.state = {        
        ReturnMessage:""
      };
    }
    
    ClearData(context){
        this.setState({
           ReturnMessage:e.target.value
        });
        context.state.ReturnMessage = ReturnMessage
    }

    render() {
        return (
           <MyContext.Consumer>                 
              {(context) => <p>{context.state.Message}</p>}
              <input onChange={this.ClearData(context)} />
           </MyContext.Consumer>
       )
    }
}

所以在孩子中通过使用Consumer,我可以在孩子渲染部分显示数据。

当我想从消费者那里更新状态时,我遇到了一个问题。

如何更新提供者状态或操纵提供者状态?

标签: javascriptreactjsreact-context

解决方案


您可以使用 useContext 挂钩来实现这一点。在 Provider 的子元素中使用它非常容易。举个例子...

authContext.js

import { createContext } from "react";

const authContext = createContext({
  authenticated: false,
  setAuthenticated: (auth) => {}
});

export default authContext;

Login.js(使用上下文的组件)

import React, { useContext } from "react";
import authContext from "./authContext";

export default () => {
  const { setAuthenticated } = useContext(authContext);
  const handleLogin = () => setAuthenticated(true);
  const handleLogout = () => setAuthenticated(false);

  return (
    <React.Fragment>
      <button onClick={handleLogin}>login</button>
      <button onClick={handleLogout}>logout</button>
    </React.Fragment>
  );
};

最后是 index.js

import ReactDOM from "react-dom";
import React, { useState } from "react";

import authContext from "./authContext";
import Login from "./Login";

const App = () => {
  const [authenticated, setAuthenticated] = useState(false);

  return (
    <authContext.Provider value={{ authenticated, setAuthenticated }}>
      <div> user is {`${authenticated ? "" : "not"} authenticated`} </div>
      <Login />
    </authContext.Provider>
  );
};

ReactDOM.render(<App />, document.getElementById("container"));

如您所见,使用 useContext 挂钩来使用存储在上下文中的数据变得非常容易。当然,就像每个 React 钩子一样,它只适用于功能组件。

如果你想看到代码工作。 https://codesandbox.io/s/react-playground-forked-wbqsh?file=/index.js


推荐阅读