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

news/2024/7/6 1:04:57

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上下文


http://www.niftyadmin.cn/n/3649572.html

相关文章

[C#]利用VSTO操作Office文档而无需安装Office

[C#]利用VSTO操作Office文档而无需安装Office编写者日期关键词郑昀ultrapower2005-8Vsto office c# Interop word1.1. VSTOVSTO&#xff0c;就是Visual Studio Tools for the Microsoft Office System。可以在这里找到更多信息&#xff1a;http://msdn.microsoft.com/office/un…

使用john 软件破解CentOS系统用户密码

时隔18天&#xff0c;我的博客终于又更新啦。最近真的是忙的不要不要的&#xff01; 一、新建两个用户用于被破解对象 新建用户Root:useradd Root 设置Root的密码&#xff1a;passwd Root 新建用户admin:useradd admin 设置admin的密码&#xff1a;passwd admin二、在centos系…

Intent 详解(一)

前言&#xff1a;通过重新翻看android入门书籍&#xff0c;才发现原来自己露掉了那么多基础知道。原以为有了C的基础&#xff0c;快速开发应该是没有问题的了&#xff0c;但没有遇到问题的时候还是海搜&#xff0c;只知道这么写能完成这个功能&#xff0c;但为什么要这么写还是…

[ASP.NET]重构Session确实让代码简洁干净了不少

CodeProject的这篇文章确实对我有所启迪&#xff0c;http://www.codeproject.com/useritems/SessionWrapper.asp#xx1208856xx。诚如作者所说&#xff0c;我们经常在ASP.NET用许多类似于下面的代码来检测Session中存储的对象&#xff0c;来防止Session过期后存储的变量丢失问题&…

redis修改配置重启命令_如何从命令行更改Redis的配置

redis修改配置重启命令介绍 (Introduction) Redis is an open-source, in-memory key-value data store. Redis has several commands that allow you to make changes to the Redis server’s configuration settings on the fly. This tutorial will go over some of these c…

SSH连接工具FinalShell的安装与使用

常见的SSH连接工具有好多&#xff0c;我以前常用的是xshellxftp组合。虽然需要付费&#xff0c;但是免费版已经基本满足我的需求。关于xshell和xftp的安装和使用可以参考我以前的博客&#xff1a;Xftp和Xshelll的安装—远程连接linux FinalShell是一体化的的服务器,网络管理软件…

[j2me]利用kSOAP让MIDP设备与WebService之间传递类对象

[j2me]利用kSOAP让MIDP设备与WebService之间传递类对象编写者日期关键词郑昀ultrapower2005-8-14J2me webservice soa ksoap serialization MIDP CLDC中国移动GPRS网络的连接方式有两种类型&#xff0c;一种是WAP&#xff0b;GPRS&#xff0c;接入名称叫CMWAP&#xff0c;一种是…

盖茨比乔布斯_盖茨比中的自定义字体

盖茨比乔布斯Choosing the right font can add great value to a site and enhance the user experience. The right font-loading strategy, however, can be somewhat of a challenge. That’s why Gatsby provides several developer-friendly solutions for all of our fon…