As much as I would love to chat about how cool Dustin Hoffman’s shiny hand toothpick looks, we are not going to chat about the movie Hook. We are here to talk very briefly about React Hooks! As I am learning React, I have come across a lot of code written with Hooks. Since I didn’t understand it at first, here‘s my attempt to explain… Hooks.
尽管我想谈谈达斯汀·霍夫曼(Dustin Hoffman)闪闪发亮的手牙签看起来如何酷,但我们不会谈论电影《胡克》。 我们在这里非常简单地谈论React Hooks! 在学习React的过程中,我遇到了很多用Hooks编写的代码。 由于我一开始不了解,因此请尝试解释一下。
Note: If you have questions on React or Hooks, please check out the great documents the React team has put together here and here. I am just going to cover two examples of the basics.
注意:如果您对React或Hooks有疑问,请查看React团队 在此处 和 此处 整理的重要文档 。 我将仅介绍两个基本示例。
What is a React Hook? Introduced on February 6, 2019, Hooks are a way of creating components without creating a class! Hooks let you manipulate state and other React features of the component lifecycle from functional components.
什么是React Hook? Hooks于2019年2月6日推出,是一种无需创建类即可创建组件的方法! 挂钩使您可以从功能组件操纵组件生命周期的状态和其他React功能。
But why should I care? If you are familiar with building out big components you may find yourself running into difficulty refactoring or you may have paralleled or duplicated logic, or worse heavily nested components referred to as wrapper hell.
但是我为什么要关心呢? 如果您熟悉构建大型组件,则可能会遇到重构困难,或者逻辑并行或重复,或者嵌套更糟的组件称为包装器地狱。
https://www.slideshare.net/AikdanaiSidhikosol/react-hooks-101 https://www.slideshare.net/AikdanaiSidhikosol/react-hooks-101Hooks help us stay DRY and makes our code more organized and reusable by breaking down reusable code into smaller functions.
挂钩通过将可重用的代码分解为较小的函数来帮助我们保持DRY状态 ,并使我们的代码更有条理和可重用。
Let’s take a look at two examples to explain how hooks are helpful useState and useEffect.
让我们看两个示例,以说明钩子如何对useState和useEffect有用。
Without Hooks: Below is an example of a stateful component in React without Hooks.
不带钩子:以下是React 不带钩子的有状态组件的示例。
import React from "react"export default class App extends React.Component { state = { count: 0, } render() { return ( <div> <p>You clicked {this.state.count} times</p> <button onClick={() => this.setState({count: this.state.count + 1}>Click me</button> </div> ) }}What we are doing here is defining a stateful class component where we initialize the state of the count at 0. After rendering, if the user clicked on the button “Click me”, we will increment the state count by 1. Pretty straight forward right.
我们在这里所做的是定义一个有状态的类组件,在其中将计数的状态初始化为0。渲染后,如果用户单击“ Click me”按钮,我们将状态计数增加1。 。
With Hooks:
带挂钩:
import React, { useState } from "react"const App = () => { const [count, setCount] = useState(0) return ( <div> <p>You clicked {count} times</p> <button onClick={ Click me </button> </div> )}export default AppAs you may have noticed, this looks like a functional component named ‘App’ and you’re right that is because it is! But with the import React, { useState } from "react" line, we are ‘hooking’ into React features and getting access to useState in the ‘App’ functional component. Basically the point here is that whereas previously you had to create a class to add state, now you can ‘hook’ into the React feature for setting and changing state!
您可能已经注意到,这看起来像一个名为“ App”的功能组件,您说对了,因为是这样! 但是在import React, { useState } from "react" 在这一行中,我们正在“加入” React功能,并能够访问“ App”功能组件中的useState 。 基本上,这里的要点是,以前您必须创建一个添加状态的类,而现在您可以“挂钩”到React功能中以设置和更改状态!
By importing and calling useState, we get two values. A value or variable to manipulate state, and a function to do the action of manipulating of state. In this example, the first value we are using iscountwhich will hold the count that we will increment, just like the oldthis.setState(count: …. The second value is the setCount function that will update thecount by 1. The count is being initialized with zero by passing0 as the only useState argument. In the class component example, we’re using this.state.count + 1 to increment, but with the useState hook, we are using count + 1 . Look how nice and clean that is! So with useState you’ll notice we get const [count, setCount] = useState(0). Or const [firstValue, functionToRun] = useState(initialized state). Check out the very well documented deeper dive here.
通过导入和调用useState,我们得到两个值。 用于操作状态的值或变量,以及用于执行状态操作的函数。 在此示例中,我们使用的第一个值是count ,它将保存要增加的计数,就像旧的this.setState(count: … 。)。第二个值是setCount函数,该函数会将count更新为1。通过将0传递为唯一的useState参数,将count初始化为零,在类组件示例中,我们使用this.state.count + 1进行递增,但是通过useState挂钩,我们使用count + 1 。因此,使用useState会发现我们得到const [count, setCount] = useState(0)或const [firstValue,functionToRun] = useState(initialized state)。请在此处查看详细记录的更深入的资料。
This is pretty cool, now let’s look at another hook called the Effect hook with useEffect. “The Effect Hook lets you perform side effects in function components”. What are side effects you may ask? Side effects are parts of the app (some bit of code) that get impacted or executed outside the scope of the function that just got executed. Examples of this are fetching asynchronous data from an API or a function that changes the global variable in a component after execution.
这非常酷,现在让我们看看另一个带有useEffect的挂钩,称为效果挂钩。 “效果挂钩可让您在功能组件中执行副作用”。 您可能会问什么副作用? 副作用是应用程序的一部分(一些代码),在刚刚执行的功能范围之外受到影响或执行。 这样的示例是从API或执行后在组件中更改全局变量的函数中获取异步数据。
Take a look at this diagram from the man himself Dan Abramov. This is a very good graphical representation of the component lifecycle
看看这个人本·丹·阿布拉莫夫(Dan Abramov)的这张图 。 这是组件生命周期的非常好的图形表示
https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/ https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/‘Render phase’ Pure and has no side effects. May be paused, aborted or restarted by React.
“渲染阶段”纯净,无副作用。 可被React暂停,中止或重启。
‘Commit phase’ Can work with DOM, run side effects, schedule updates.
“提交阶段”可以使用DOM,运行副作用,安排更新。
Check out these comments above ^. What this means is that we want to only run these bits of code that may affect other parts of our application out of scope in the ‘commit phase’. The Effect hook is effectively these lifecycle components: componentDidMount, componentDidUpdate, and componentWillUnmount. What we want to do is utilize these lifecycle methods in a DRYer way with useEffect.
在上方查看这些评论。 这意味着我们只希望运行这些可能在“提交阶段”超出范围的代码位,这些代码可能会影响应用程序的其他部分。 Effect挂钩实际上是这些生命周期组件: componentDidMount , componentDidUpdate和componentWillUnmount 。 我们要做的是通过useEffect以DRYer方式利用这些生命周期方法。
For the fetch example, you would usually add the fetch in the componentDidMount() function. But what if you didn’t? What if you ran this fetch call that has a side effect, in the constructor, for example? How would you see the results after render and seeing the results in the DOM(in HTML)? How would the rest of the lifecycle run and unmount if the side effect of the fetch call is not properly rendered or read when compiling your code? Or what if there is a failed or rejected promise or bad call before mounting and rendering that result? How would you abort that function? As you can imagine this can cause many errors related to the order of mounting and unmounting with regards to the component lifecycle.
对于获取示例,通常将获取添加到componentDidMount()函数中。 但是,如果没有,该怎么办? 例如,如果您在构造函数中运行了具有副作用的提取调用,该怎么办? 渲染并在DOM(HTML)中看到结果后,您将如何看待结果? 如果在编译代码时未正确呈现或读取fetch调用的副作用,生命周期的其余部分将如何运行和卸载? 或者,如果在挂接和呈现结果之前出现失败或拒绝的承诺或错误的通话,该怎么办? 您将如何中止该功能? 可以想象,这会导致许多错误,这些错误与组件生命周期的安装和卸载顺序有关。
Here is the continuation of the example from the React docs.
这是React文档中示例的延续。
import React from "react"class Example extends React.Component {state = { count: 0 }; } componentDidMount() { document.title = `You clicked ${this.state.count} times`; }componentDidUpdate() { document.title = `You clicked ${this.state.count} times`; } render() { return ( <div> <p>You clicked {this.state.count} times</p> <button onClick={() => this.setState({count: this.state.count + 1 })}>Click me</button> </div> ); }}You can see that here the goal is on mount of the component and on update we want to set the current title of the document to the “You clicked some number of times’. When you mount the component, show the initialized state, then when the user clicks on the button, show the updated state. We have to labor over writing two methods to do this.
您可以看到这里的目标是安装组件并进行更新,我们希望将文档的当前标题设置为“您单击了几次”。 当您安装组件时,显示初始化状态,然后当用户单击按钮时,显示更新状态。 为此,我们必须努力编写两种方法。
Enter the Effect hook:
输入效果挂钩:
import React, { useState, useEffect } from 'react';function Example() { const [count, setCount] = useState(0); useEffect(() => { document.title = `You clicked ${count} times`; }); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> );}As you can see again we import the useEffect hook from react, trade our class for a functional component, and now only have to write 1 function for both lifecycle functions, shortening our code and making it clean! What the Effect hook is doing here, is that it is going to remember the first function to render and subsequently re-render on update. Something important to note is that “By default, it runs both after the first render and after every update.”
再次您可以看到,我们从react导入useEffect钩子,将类换为功能组件,现在两个生命周期函数只需要编写1个函数,从而缩短了代码并使其变得干净! Effect挂钩在这里所做的是,它将记住要渲染的第一个函数,然后在更新时重新渲染。 需要注意的重要一点是:“默认情况下,它在第一次渲染后和每次更新后都运行。”
So overall these two examples show the very high-level basic benefits for using hooks. It allows us to be more succinct, DRY, and organized with code, and run more efficiently. I hope this was helpful. Here are all the resources:
因此,总体而言,这两个示例显示了使用钩子的非常高级的基本好处。 它使我们可以更简洁,更干燥,更井井有条,并且运行效率更高。 我希望这可以帮到你。 这是所有资源:
State Hook
状态钩
Effect Hook
效果钩
翻译自: https://medium.com/@jacobosity/basic-hooks-55677943d8da
相关资源:四史答题软件安装包exe