admin管理员组

文章数量:1565799

react hooks使用

Context is probably my favorite React feature, especially when using hooks. It’s not bleeding edge tech anymore, so you should take a second to learn how it works. We’re just going to create a Context component, and then read/set values from it in our main app. It’s going to be a very simple project, but one that shows the basics and how you can build on it in the future. Here is the code on GitHub.

上下文可能是我最喜欢的React功能,尤其是在使用钩子时。 它不再是前沿技术,因此您应该花一点时间来学习它的工作原理。 我们将创建一个Context组件,然后在主应用程序中从中读取/设置值。 这将是一个非常简单的项目,但将展示基础知识以及将来如何在此基础上进行开发。 这是GitHub上的代码 。

什么是上下文? (What is Context?)

Context lets you have global properties and functions that can be accessed from anywhere in your project. This is pretty much what Redux does, and the best way to distinguish Redux from Context is size: Context is smaller and simpler. The model for a Redux Store is usually a intricate, immutable object, whereas with Context it would be more helpful if you think about it like a floating component that can talk to any other component. You also don’t have to use reducers, which can also drastically simplify things.

上下文使您可以从项目中的任何位置访问全局属性和函数。 这几乎是Redux所做的,将Redux与Context区分开的最佳方法是大小:Context较小且更简单。 Redux Store的模型通常是一个复杂的,不可变的对象,而使用Context时,如果将其视为可以与任何其他组件进行通信的浮动组件,则将更加有用。 您也不必使用reducer,这也可以大大简化事情。

建立 (Setup)

Use create-react-app and that’s it. We aren’t going to have any external dependencies. We’re going to create a Context component, give it an internal state, and then share that state with the rest of our app. All our app is actually going to *do* is save an input string to Context. I encourage you to read them all the same. It’s good to know both the hooks and state version, since your company may not be using the latest React.

使用create-react-app就是这样。 我们不会有任何外部依赖性。 我们将创建一个Context组件,为其提供内部状态,然后与我们的其他应用程序共享该状态。 实际上,我们所有要做的* do *应用都是将输入字符串保存到Context中。 我鼓励您同样阅读它们。 很高兴知道钩子和状态版本,因为您的公司可能未使用最新的React。

步骤1:创建一个上下文组件 (Step 1: Create a Context component)

In src/ create a context/ directory and inside it put index.js and ContextProvider.js. Let’s fill out index.js first:

src/创建一个context/目录,并在其中放置index.jsContextProvider.js 。 让我们先填写index.js

import React from 'react';const AppContext = React.createContext({});export default AppContext;

I’m going to explain that second line, but first let’s also create ContextProvider.js:

我将解释第二行,但首先我们还要创建ContextProvider.js

import React, { useState } from 'react';
import AppContext from '.';const ContextProvider = ({ children }) => {
const [example, setExample] = useState('Hello there')
const context = {
setExample,
example,
}; return (
<AppContext.Provider value={ context }>
{children}
</AppContext.Provider>
);
}export default ContextProvider;

步骤1a:我们做了什么 (Step 1a: What did we do)

Alright, let’s talk about createContext and AppContext.Provider. We actually create our Context in index.js, this is the “raw” Context if you will. See, context itself is really just a value, but React incorporates it into its system and gives it Consumer and Provider components. Now, hooks let us bypass the need for a Consumer component, but we still need to have a parent Provider component.

好了,让我们谈谈createContextAppContext.Provider 。 实际上,我们在index.js创建了Context,如果可以的话,这就是“原始” Context。 看到,上下文本身实际上只是一个值,但是React将它合并到其系统中并赋予它ConsumerProvider组件。 现在,钩子让我们绕过了对Consumer组件的需求,但是我们仍然需要有一个父Provider组件。

What our provider component does is take a value (we’re calling it context, but it can be named anything) and then make it accessible to any of the children components. This value is essentially our global store. Also, if you aren’t familiar with children props, we’ll talk about it in the next step.

什么我们提供组件确实是需要一个value (我们称其为context ,但它可以被命名为任何东西),然后使其任意的访问children成分。 此value实质上是我们的全球商店。 另外,如果您对children道具不熟悉,我们将在下一步中讨论。

内部状态 (Internal state)

Notice what we pass into our context value: it’s a useState hook and its accompanying value. That’s the best part about this setup, we’re simply tracking a regular component’s state. When an external component needs to update the store, there’s no magic, it’s merely updating the internal state of the Context component. That change is then updated wherever it gets read, like a different version of props. There’s nothing new here except where the data is being stored. You can of course add as much as you like to this object, but for now we’re keeping it pretty bare bones.

注意我们传递给context值的内容:这是一个useState挂钩及其附带的值。 这是此设置的最佳部分,我们只是在跟踪常规组件的状态。 当外部组件需要更新商店时,没有什么魔力,它只是更新Context组件的内部状态。 然后,无论读取到什么地方,该更改都会更新,就像其他版本的道具一样。 除了存储数据的位置以外这里没有其他新内容。 当然,您可以根据需要添加任意数量的对象,但是现在,我们将其保留为裸露的骨头。

第2步:将上下文插入应用程序 (Step 2: Plug your Context into your app)

In order for Context to do anything, we need to make it available. Any child component of our ContextProvider component will have access to the store. That means, we need to put it somewhere very high up in the component chain, so I usually put it at the top in the src/index.js file:

为了使Context做任何事情,我们需要使其可用。 我们的ContextProvider组件的任何子组件都可以访问商店。 这意味着,我们需要将其放在组件链中很高的位置,因此我通常将其放在src/index.js文件的顶部:

import React from 'react';
import ReactDOM from 'react-dom';
import ContextProvider from './context/ContextProvider';
import App from './App';ReactDOM.render(
<React.StrictMode>
<ContextProvider>
<App />
</ContextProvider>
</React.StrictMode>,
document.getElementById('root')
);

This is also where the children prop in our ContextProvider comes into play. Recall our return statement in our provider component:

这也是对children在我们的道具ContextProvider进场。 回顾我们提供者组件中的return语句:

return (
<AppContext.Provider value={ context }>
{children}
</AppContext.Provider>
);

By nesting out <App> inside <ContextPrivider>, our main app and all its child components are now the children of the <AppContext.Provider> component. That’s what actually lets our app get access to our Context and prevents unnecessary renders. Here’s a quick article on props.children if you aren’t familiar with it.

通过将<App>嵌套在<ContextPrivider> <App>内部,我们的主应用程序及其所有子组件现在是<AppContext.Provider>组件的子组件。 这实际上是让我们的应用访问我们的上下文并防止不必要的渲染的原因。 如果您不熟悉props.children,这里有一篇简短的文章 。

步骤3:在组件中使用上下文 (Step 3: Use your Context in a component)

Alright, here we go! All we’re going to make is a little form that lets us set the string value of example in our Context. And we’ll display it with the useEffect hook and a console log. We’re going to keep things simple and do it all in our main src/app.js file:

好了,我们开始! 我们要做的只是一个小的形式,它使我们可以在Context中设置example的字符串值。 我们将使用useEffect钩子和控制台日志来显示它。 我们将使事情保持简单,并在主src/app.js文件中完成所有操作:

import React, { useContext, useState, useEffect } from 'react';import './App.css';import AppContext from './context';const App = () => {
const { example, setExample } = useContext(AppContext);
const [formText, setFormText] = useState(''); useEffect(() => {
console.log('context here: ', example);
}, [example]);

const handleChange = (e) => {
setFormText(e.target.value);
}; const handleSubmit = (e) => {
e.preventDefault();
setExample(formText);
};

return (
<div className="App">
<form onSubmit={handleSubmit}>
<label htmlFor="example">Example: </label>
<input
type='text'
value={formText}
onChange={handleChange}
/>
<button>DO IT</button>
</form>
</div>
);
};export default App;

There’s the whole thing, and here are the parts that use Context:

整个过程都在进行,这是使用上下文的部分:

import AppContext from './context'; 
// ...const App = () => {
const { example, setExample } = useContext(AppContext); useEffect(() => {
console.log('context here: ', example);
}, [example]);// ... const handleSubmit = (e) => {
e.preventDefault();
setExample(formText);
};

return (
// ...
<input
type='text'
value={formText}
onChange={handleChange}
/>

We just feed our Context into the useContext hook and then pull out the properties we want to use. The way you use those properties is pretty much the same as you would a useState function or value. Remember the Context object is the one defined in index not the ContextProvider component, that’s only ever used in a single place. This is surprisingly simple, but that’s all thanks to hooks. They all work together seamlessly that Context really fits right in.

我们只是将Context放入useContext钩子中,然后提取我们要使用的属性。 使用这些属性的方式与useState函数或值几乎相同。 请记住,Context对象是在index定义的对象,而不是ContextProvider组件,它只能在单个位置使用。 这非常简单,但这全都归功于钩子。 他们都可以无缝协作,从而使Context真正适合。

差不多了 (That’s pretty much it)

There used to be a bit more pomp and circumstance when using Context with class based components, but hooks make it like another useState (if you need class based components, check out Wes Bos’s tutorial, I just adapted the pattern for hooks). And of course things can get more complex, like multiple Contexts or a useReducer instead of useState, but at it’s core, it’s a simple concept.

在将Context与基于类的组件一起使用时, useState情况,但是钩子使它像另一个useState (如果您需要基于类的组件, 请 useState Wes Bos的教程 ,我只是为钩子改编了模式)。 当然,事情可能会变得更复杂,例如多个Context或一个useReducer而不是useState ,但是从useState ,这是一个简单的概念。

happy coding everyone,

祝大家编码愉快,

mike

麦克风

翻译自: https://levelup.gitconnected/how-to-use-context-with-react-hooks-5591a4010689

react hooks使用

本文标签: 上下文如何在hooksReact