阅读 259

React Hooks教程--useState、useEffect以及如何创建自定义钩子

钩子是在React 16.8中首次引入的。它们非常棒,因为它们可以让你使用更多的React功能--比如管理你的组件的状态,或者在状态发生某些变化时执行后置效果,而不需要写一个类。

在这篇文章中,你将学习如何在React中使用Hooks,以及如何创建你自己的自定义Hooks。请记住,你可以只对功能组件使用钩子。

什么是useState Hook?

你的应用程序的状态一定会在某个时刻发生变化。这可能是一个变量的值,一个对象,或者你的组件中存在的任何类型的数据。

为了使这些变化能够反映在DOM中,我们必须使用一个叫做useState 的React钩子。它看起来像这样。

import { useState } from "react"; function App() {   const [name, setName] = useState("Ihechikara");   const changeName = () => {     setName("Chikara");   };   return (     <div>       <p>My name is {name}</p>       <button onClick={changeName}> Click me </button>     </div>   ); } export default App; 复制代码

让我们再仔细看一下上面的代码是怎么回事。

import { useState } from "react"; 复制代码

为了能够使用这个钩子,你必须从React中导入 useState 钩子。我们正在使用一个名为app 的功能组件。

const [name, setName] = useState("Ihechikara"); 复制代码

之后,你必须创建你的状态,并给它一个初始值(或初始状态),它是 "Ihechikara"。这个状态变量被称为name ,而setName 是用于更新其值的函数。

对ES6的一些特性有一个很好的理解将有助于你掌握React的基本功能。上面,我们用destructuring赋值为useState("Ihechikara") 中的状态分配了一个初始名称值。

return (     <div>       <p>My name is {name}</p>       <button onClick={changeName}> Click me </button>     </div>   ); } 复制代码

接下来,DOM有一个包含名字变量的段落和一个按钮,点击后会触发一个函数。changeName() 函数调用setName() 函数,然后将名称变量的值改为传递给setName() 函数的值。

你的状态值不能是硬编码的。在下一节,你将看到如何在表单中使用useState 钩子。

对于React的初学者来说,请注意你在返回语句之前创建你的函数和变量。

如何在表单中使用useState钩子

本节将帮助你了解如何为你的表单创建状态值,并在需要的时候更新它们。这个过程与我们在上一节中看到的并无太大区别。

像往常一样,导入useState 钩子。

import { useState } from "react"; 复制代码

我们将像之前那样创建初始状态。但在这种情况下,它将是一个空字符串,因为我们要处理的是一个输入元素的值。硬编码值意味着每当页面被重新加载时,输入元素就会有这个值。就是说。

  const [name, setName] = useState(""); 复制代码

现在我们已经创建了状态,让我们在DOM中创建输入元素,并将name变量分配为它的初始值。它看起来像这样。

return (     <div>       <form>         <input           type="text"           value={name}           onChange={(e) => setName(e.target.value)}           placeholder="Your Name"         />         <p>{name}</p>       </form>     </div>   ); 复制代码

你会注意到,我们没有在返回语句上方创建一个函数来更新状态的值--但如果你决定使用这种方法,还是可以的。

在这里,我们使用onChange 事件监听器,它等待着输入字段中任何数值的变化。每当有变化时,一个匿名函数(以事件对象为参数)被触发,它反过来调用setName() 函数,用输入字段的当前值更新名称变量。

下面是最终代码的样子。

import { useState } from "react"; function App() {   const [name, setName] = useState("");   return (     <div>       <form>         <input           type="text"           value={name}           onChange={(e) => setName(e.target.value)}           placeholder="Your Name"         />         <p>{name}</p>       </form>     </div>   ); } export default App; 复制代码

什么是useEffect Hook?

效果钩子,就像它的名字所暗示的那样,在每次有状态变化时执行一个效果。默认情况下,它在第一次渲染后和每次状态更新时运行。

在下面的例子中,我们创建了一个状态变量count ,初始值为0。每次点击DOM中的一个按钮,这个变量的值就会增加1。useEffect钩子将在每次count 变量变化时运行,然后向控制台记录一些信息。

import { useState, useEffect } from "react"; function App() {   const [count, setCount] = useState(0);   useEffect(() => {     console.log(`You have clicked the button ${count} times`)   });   return (     <div>       <button onClick={() => setCount(count + 1)}>Click me</button>     </div>   ); } export default App; 复制代码

如果你要 "钩住 "这个React功能,你导入所需钩子的第一行代码总是很重要。我们导入了上面使用的两个钩子。

import React, { useState, useEffect } from "react"; 复制代码

注意,你可以使用useEffect钩子来实现各种效果,比如从外部API获取数据(你会在本文的另一节看到),改变组件中的DOM,等等。

useEffect的依赖性

但是如果你想让你的效果只在第一次渲染后运行,或者你有多个状态,而只想在其中一个状态下附加一个后置效果,该怎么办?

我们可以通过使用一个依赖数组来做到这一点,该数组在useEffect 钩子中作为第二个参数传入。

如何运行一次效果

对于第一个例子,我们将传入一个数组,让useEffect钩子只运行一次。下面是一个关于如何工作的例子。

import { useState, useEffect } from "react"; function App() {   const [count, setCount] = useState(0);   useEffect(() => {     console.log(`You have clicked the button ${count} times`)   }, []);   return (     <div>       <button onClick={() => setCount(count + 1)}>Click me</button>     </div>   ); } export default App; 复制代码

上面的代码与上一节相同,只是useEffect钩子接受一个空数组[] 作为第二个参数。当我们让数组为空时,效果将只运行一次,而不考虑它所连接的状态的变化。

如何将一个效果附加到一个特定的状态

import { useState, useEffect } from "react"; function App() {   const [count, setCount] = useState(0);   useEffect(() => {     console.log(`You have clicked the first button ${count} times`);   }, [count]);   const [count2, setCount2] = useState(0);   useEffect(() => {     console.log(`You have clicked the second button ${count2} times`)   }, [count2]);   return (     <div>       <button onClick={() => setCount(count + 1)}>Click me</button>       <button onClick={() => setCount2(count2 + 1)}>Click me</button>     </div>   ); } export default App; 复制代码

在上面的代码中,我们创建了两个状态和两个useEffect钩子。每个状态都有一个后置效果,通过将状态的名称[count][count2] 传递给相应的useEffect数组依赖。

因此,当count 的状态发生变化时,负责观察这些变化的useEffect钩子将执行分配给它的任何后效应。这也适用于count2

如何创建你自己的钩子

现在你已经看到了React中的一些内置钩子(查看文档以查看更多的钩子),现在是时候创建我们自己的自定义钩子了。

你的钩子能做什么有很多可能性。在本节中,我们将创建一个钩子,从外部API获取数据,并将数据输出到DOM中。这可以节省你在不同的组件中重复创建相同逻辑的压力。

第1步 - 创建你的文件

当为自定义钩子创建一个新的文件时,一定要确保文件的名字以 "use "开头。我将我的文件称为useFetchData.js

第2步 - 创建钩子的功能

如前所述,我们将使用这个钩子从外部API获取数据。它将是动态的,所以没有什么需要硬编码的。下面是我们要做的。

import { useState, useEffect} from 'react' function useFetchData(url) {     const [data, setData] = useState(null);     useEffect(() => {       fetch(url)         .then((res) => res.json())         .then((data) => setData(data))         .catch((err) => console.log(`Error: ${err}`));     }, [url]);     return { data }; } export default useFetchData 复制代码

为了解释上面发生的事情。

  • 我们导入钩子:import { useState, useEffect} from 'react'

  • 我们创建一个状态来保存将被返回的数据--初始状态将是空的:const [data, setData] = useState(null); 。返回的数据将使用setData() 函数更新data 变量的值。

  • 我们创建一个效果,在第一次渲染和每次url 参数变化时运行。

useEffect(() => {       fetch(url)         .then((res) => res.json())         .then((data) => setData(data))         .catch((err) => console.log(`Error: ${err}`));     }, [url]); 复制代码

  • 我们返回数据变量。return { data };

第3步 - 创建一个新文件并导入自定义钩子

所以我们已经创建了我们的自定义钩子。现在让我们创建一个新的组件,看看我们如何在其中使用useFetchData 钩子。

import useFetchData from './useFetchData'   function Users() {     const { data } = useFetchData("https://api.github.com/users");   return (       <div>           {data && (             data.map((user) =>(                 <div className="text-white" key={user.id}>                     <h1> {user.login} </h1>                     <p> { user.type } </p>                 </div>             ))           )}       </div>   ) } export default Users; 复制代码

让我们把它分解一下。

  • 我们将该组件命名为Users.js ,因为它将用于从GitHub的API(可以是任何API)获取用户数据。

  • 我们导入了一个自定义钩子:import useFetchData from './useFetchData'

  • 我们在返回语句前引用了这个钩子,并传入了URL。const { data } = useFetchData("https://api.github.com/users"); 。一个API请求将被发送到你传入的任何URL。

  • 使用&& 操作符,只有当数据变量被来自API请求的数据更新时,DOM才会被更新,也就是说,当data != null

  • 我们对返回的数据进行循环,并将其输出到DOM中。

总结

如果你已经跟进到这一点,那么你应该对React中的钩子有一个很好的理解,如何使用它们,以及如何创建你自己的自定义钩子。而完全理解这些的最好方法是实践,所以不要只是通读。

这篇文章涵盖了钩子的核心领域,但它不会教你关于钩子的所有知识。所以请确保你查看React JS文档,以便你能了解更多关于它们的信息。


作者:迪鲁宾
链接:https://juejin.cn/post/7023213712789995550


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐