从嵌套的 class 组件更改 React Context 中的值

Change values in React Context from a nested class component

我有这个 userContext 文件:

import React from 'react'

const userContext = React.createContext({ loggedInUser: {} })

export { userContext }

我在 App 中提供了正确的值:

import { userContext } from './../contexts/UserContext'

class App extends Component {
           //...
    
  componentDidMount = () => {
    this.authServices
      .isLoggedIn()
      .then(response => this.setState({ loggedInUser: response.data })
      .catch(() => this.setUser(undefined))
  }

    
        return (
          <>
            <userContext.Provider value={this.state.loggedInUser}>
              <Navigation/>
            </userContext.Provider>
          </>
        )
    }

并且可以在任何嵌套组件中访问该值,例如 Navigation:

/* ... */
<userContext.Consumer>
    {value => value && <h1>Hi! {value.username}</h1>}
</userContext.Consumer>
/* ... */

如何从上下文中的 loggedInUser 属性 等嵌套组件(例如 Navigation 更改值?

我找不到将方法附加到上下文并使用它们的方法,例如,当用户在 Navigation 组件中注销时:

/* ... */

logOut = () => {
    this.authService
        .logout()
        .then(() => /* modify here the loggedInUser from the context */ )

/* ... */

请注意这是一个有状态组件,我需要一个非 Hooks 解决方案。

您需要修改您的上下文文件并在上下文文件本身中设置您的 method,如下所示:

export const UserContext = createContext();

class UserContextProvider extends Component {
    state={
       loggedInUser: {}
    }
  /* ---Logout method here also --- */

   logOut = () => {
     this.authService
    .logout()
    .then(() => {} /* modify here the loggedInUser from the context */ )
   }
    render() {
        return (
            <UserContext.Provider value={{...state},logout:{this.logout}>
                {this.props.children}
            </UserContext.Provider>
        )
    }
}

export default UserContextProvider;

您还需要更新 App.js 文件,以便 {this.props.children} 在上下文文件中正常工作:

import UserContextProvider from './userContext.js'; // import as per your path

<UserContextProvider>
  <div className="App">
      <Navigation/>
  </div>
</UserContextProvider>

并且你的Consumer文件修改如下:

<userContext.Consumer>
   >{(context)=>{
        const {loggedInUser,logout} = context;
         return(
           <div>
             // Your JSX as per your condition
           </div>
        )


</userContext.Consumer>

您可以访问我的 github Context API 项目以了解有关 Context 的更多信息-API: 您将学习上下文创建以及使用和不使用 useContext 的不同方式来使用上下文。

https://github.com/emmeiwhite/Context-API

首先,您需要创建一个函数来更改用户数据并将其传递到上下文中,以便子组件可以利用它。

updateUserData = (userInfo) => {
  this.setState({ loggedInUser: userInfo })
}

之后,您可以在上下文中传递该函数:

<userContext.Provider value={{
  loggedInUser: this.state.loggedInUser,
  updateUserData: this.updateUserData
}}>
  <Navigation/>
</userContext.Provider>

由于您正在访问上下文 Provider 您将需要以旧方式附加 class 之上的 static contextType = userContext; 以便能够在渲染方法之外访问这样的上下文值:

const { loggedInUser, updateUserData } = this.context;

现在在您的 logOut 中访问 updateUserData 并传递新的 userData.

这里是关于 contextType 的更多信息: https://reactjs.org/docs/context.html#classcontexttype