在渲染功能之外访问React Context

我正在使用新的React Context API而不是Redux开发一个新应用,并且在使用之前,例如Redux,当我需要获取用户列表时,我只是调用componentDidMount我的操作,但是现在使用React Context,我的操作可以在内部进行。我的用户位于我的渲染函数中,这意味着每次调用我的渲染函数时,它将调用我的操作以获取用户列表,但这不好,因为我将执行许多不必要的请求。


那么,如何只能一次调用动作,例如in componentDidMount而不是调用render?


只是为了举例说明,请看以下代码:


假设我将所有内容包装Providers在一个组件中,如下所示:


import React from 'react';


import UserProvider from './UserProvider';

import PostProvider from './PostProvider';


export default class Provider extends React.Component {

  render(){

    return(

      <UserProvider>

        <PostProvider>

          {this.props.children}

        </PostProvider>

      </UserProvider>

    )

  }

}

然后,我将这个Provider组件包装了所有应用程序,如下所示:


import React from 'react';

import Provider from './providers/Provider';

import { Router } from './Router';


export default class App extends React.Component {

  render() {

    const Component = Router();

    return(

      <Provider>

        <Component />

      </Provider>

    )

  }

}

现在,以我的用户视图为例,它将是这样的:


import React from 'react';

import UserContext from '../contexts/UserContext';


export default class Users extends React.Component {

  render(){

    return(

      <UserContext.Consumer>

        {({getUsers, users}) => {

          getUsers();

          return(

            <h1>Users</h1>

            <ul>

              {users.map(user) => (

                <li>{user.name}</li>

              )}

            </ul>

          )

        }}

      </UserContext.Consumer>

    )

  }

}

我想要的是:


import React from 'react';

import UserContext from '../contexts/UserContext';


export default class Users extends React.Component {

  componentDidMount(){

    this.props.getUsers();

  }


  render(){

    return(

      <UserContext.Consumer>

        {({users}) => {

          getUsers();

          return(

            <h1>Users</h1>

            <ul>

              {users.map(user) => (

                <li>{user.name}</li>

              )}

            </ul>

          )

        }}

      </UserContext.Consumer>

    )

  }

}

但是,当然上面的示例不起作用,因为getUsers不存在于我的用户视图中的道具。如果有可能,正确的方法是什么?


繁华开满天机
浏览 687回答 3
3回答

MMMHUHU

随着v16.8.0中引入react-hooks ,您可以通过使用useContext钩子在功能组件中使用上下文const Users = () => {&nbsp; &nbsp; const contextValue = useContext(UserContext);&nbsp; &nbsp; // rest logic here}编辑:从版本16.6.0起。您可以通过使用上下文的生命周期的方法this.context一样class Users extends React.Component {&nbsp; componentDidMount() {&nbsp; &nbsp; let value = this.context;&nbsp; &nbsp; /* perform a side-effect at mount using the value of UserContext */&nbsp; }&nbsp; componentDidUpdate() {&nbsp; &nbsp; let value = this.context;&nbsp; &nbsp; /* ... */&nbsp; }&nbsp; componentWillUnmount() {&nbsp; &nbsp; let value = this.context;&nbsp; &nbsp; /* ... */&nbsp; }&nbsp; render() {&nbsp; &nbsp; let value = this.context;&nbsp; &nbsp; /* render something based on the value of UserContext */&nbsp; }}Users.contextType = UserContext; // This part is important to access context values在版本16.6.0之前,您可以按以下方式进行操作为了在您的生命周期方法中使用Context,您可以将组件编写为class Users extends React.Component {&nbsp; componentDidMount(){&nbsp; &nbsp; this.props.getUsers();&nbsp; }&nbsp; render(){&nbsp; &nbsp; const { users } = this.props;&nbsp; &nbsp; return(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <h1>Users</h1>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <ul>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {users.map(user) => (&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <li>{user.name}</li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </ul>&nbsp; &nbsp; )&nbsp; }}export default props => ( <UserContext.Consumer>&nbsp; &nbsp; &nbsp; &nbsp; {({users, getUsers}) => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return <Users {...props} users={users} getUsers={getUsers} />&nbsp; &nbsp; &nbsp; &nbsp; }}&nbsp; &nbsp; &nbsp; </UserContext.Consumer>)通常,您将在您的应用程序中维护一个上下文,并且将以上登录信息打包在HOC中以便重新使用是有意义的。你可以这样写import UserContext from 'path/to/UserContext';const withUserContext = Component => {&nbsp; return props => {&nbsp; &nbsp; return (&nbsp; &nbsp; &nbsp; <UserContext.Consumer>&nbsp; &nbsp; &nbsp; &nbsp; {({users, getUsers}) => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return <Component {...props} users={users} getUsers={getUsers} />;&nbsp; &nbsp; &nbsp; &nbsp; }}&nbsp; &nbsp; &nbsp; </UserContext.Consumer>&nbsp; &nbsp; );&nbsp; };};然后你可以像这样使用它export default withUserContext(User);

ibeautiful

好的,我找到了一种有限制的方法。通过该with-context库,我设法将我的所有消费者数据插入到我的组件道具中。但是,要在同一个组件中插入多个使用方很复杂,您必须使用此库创建混合使用方,这会使代码不够美观且效率低下。该库的链接:https : //github.com/SunHuawei/with-context编辑:实际上,您不需要使用提供的多上下文api,with-context实际上,您可以使用简单的api并为每个上下文创建一个装饰器,如果您想在组件中使用多个消费者,则只需在类上声明所需的装饰数!
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

React.JS