react上下文_使用React上下文管理用户登录

react上下文

It’s common in React for data to flow from top to bottom through props (parent component to children components), but this is not ideal all the time.

在React中,数据通过道具(父组件到子组件)从上到下流动是很常见的,但这并不总是很理想。

Here’s a simple example:

这是一个简单的例子:

<Page user={user} avatarSize={avatarSize} />
// ... which renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// ... which renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// ... which renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
</Link>

In the above code, only the Avatar component actually uses the user prop, however each of its ancestor (parent, grandparent, etc) components receive user and pass it down. This means that if the Avatar component needed another prop in the future, we’d have to ensure that each of its ancestor components receive and pass it down. This makes our code difficult to maintain and error-prone.

在上面的代码中,只有Avatar组件实际上使用了user道具,但是其每个祖先(父母,祖父母等)组件都接收user并将其传递给user 。 这意味着如果Avatar组件将来需要另一个道具,我们必须确保其每个祖先组件都可以接收并传递给它。 这使我们的代码难以维护且容易出错。

In reality, the user state will need to be shared across many different components, therefore passing it as a prop will result it in nesting even deeper than the above example. In this situation, it may seem like a good idea to use Redux to manage state, but many argue it should not be your first option. So if not Redux, then what?

实际上, user状态将需要在许多不同的组件之间共享,因此将其作为道具传递将导致其嵌套比上述示例还要深。 在这种情况下,使用Redux来管理状态似乎是一个好主意,但是许多人认为这不应该是您的首选 。 那么,如果不是Redux,那又如何呢?

React Context is an alternative solution to sharing data across components, without having to pass props down manually at every level. This post will explore the Context API and show how it can be used to manage user state.

React Context是一种跨组件共享数据的替代解决方案,而无需在每个级别手动传递道具。 这篇文章将探索Context API,并展示如何将其用于管理用户状态。

React.createContext (React.createContext)

The React.createContext method returns a Context object. This Context object comes with two important React components that allow for subscribing to data: Provider and Consumer.

React.createContext方法返回一个Context对象。 这个Context对象带有两个重要的React组件,它们允许订阅数据: ProviderConsumer

When React renders a component that subscribes to this Context object it will read the current context value from the closest matching Provider component above it in the tree. Let’s see what that means:

当React渲染一个订阅该Context对象的组件时,它将从树中它上面最接近的匹配Provider组件读取当前上下文值。 让我们看看这意味着什么:

src/userContext.js
src / userContext.js
const userContext = React.createContext({user: {}}); // Create a context object

export {
  userContext // Export it so it can be used by other Components
};

The createContext method takes in an optional defaultValue argument, which is provided to Context.Consumer if a matching Context.Provider component could not be found in the tree. In the example above we initialize userContext and provide defaultValue of {user: {}}.

如果在树中找不到匹配的Context.Provider组件,则createContext方法采用可选的defaultValue参数,该参数将提供给Context.Consumer 。 在上面的示例中,我们初始化了userContext并提供了{user: {}} defaultValue。

Now that we have a Context object we can provide it with a value and subscribe to changes.

现在我们有了一个Context对象,我们可以为其提供一个值并订阅更改。

上下文提供者 (Context.Provider)

src/App.js
src / App.js
import {userContext} from './userContext';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
        user: {}
    };
  }

  componentDidMount() {
    // get and set currently logged in user to state
  }

  render() {
    return (
      // Pass user state as value to context.Provider so it can be consumed by context.Consumer
      <userContext.Provider value={this.state.user}>
        <Main/>
      </userContext.Provider>
    );
  }
}

This is great to start with, wrapping the Main component with userContext.Provider ensures that the value we pass can be consumed within any of Main’s descendant child components. But how exactly do you consume?

首先,用userContext.Provider包装Main组件是很不错的userContext.Provider确保我们传递的值可以在Main的所有子组件中使用。 但是你到底怎么消费 ?

上下文消费者 (Context.Consumer)

Main.js
Main.js
import {userContext} from './userContext';

function Main(props) {
  return (
    <Sidebar/>
    <userContext.Consumer>
      {(value) => (<Avatar user={value}/>);}
    </userContext.Consumer>
    <Content/>
  )
}

userContext.Consumer takes in a function as a child. This function receives the current context value (value that is passed as a prop to userContext.Provider) and returns a React node. In this case it receives the App component’s state.user as value and renders an Avatar component.

userContext.Consumer将函数作为子级。 此函数接收当前上下文值(作为prop传递给userContext.Provider ),并返回一个React节点。 在这种情况下,它接收App组件的state.user作为值,并呈现Avatar组件。

从嵌套组件更新上下文 (Updating Context from Nested Components)

Up to this point, we’ve used React Context to pass data to components that need it without having to manually pass props. Next, we need to be able to update the context from a nested child component. A logout button, for example.

到目前为止,我们已经使用React Context将数据传递到需要它的组件,而无需手动传递prop。 接下来,我们需要能够从嵌套的子组件中更新上下文。 例如,注销按钮。

In this case, you can pass a function down through the same context to allow consumers to update the context.

在这种情况下,您可以将功能向下传递到同一上下文,以允许使用者更新上下文。

src/App.js
src / App.js
import {userContext} from './userContext';

class App extends React.Component {
  constructor(props) {
  super(props);
  this.state = {
    user: {}
  };

  this.logout = this.logout.bind(this);
  }

  // Add a logout method
  logout() {
    this.setState({user: {}});
  }

  componentDidMount() {
    // get and set currently logged in user to state
  }

  render() {
    // compose value prop as object with user object and logout method
    const value = {
      user: this.state.user,
      logoutUser: this.logout
    }
    return (
      <userContext.Provider value={value}>
        <Main/>
      </userContext.Provider>
    );
  }
}

The function that is passed to update context can be used in any nested component within the userContext.Provider component.

传递给更新上下文的函数可以在userContext.Provider组件内的任何嵌套组件中使用。

Main.js
Main.js
import {userContext} from './userContext';

function Main(props) {
  return (
  <Sidebar/>
  <userContext.Consumer>
    {({user, logoutUser}) => {
      return (
        <Avatar user={user}/>
        <LogoutButton onClick={logoutUser}/>
      );
    }}
  </userContext.Consumer>
  <Content/>
  )
}

And that concludes a simple example of how to use React’s Context API to manage user state.

并得出一个简单的示例,说明如何使用React的Context API管理用户状态。

翻译自: https://www.digitalocean.com/community/tutorials/react-manage-user-login-react-context

react上下文

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值