如何在React项目中应用ReactHooks
介绍
在本文中,您将探索 React Hooks,这是 React 最新版本 16.8 中的新功能。 React Hooks 是函数,可作为状态和生命周期方法的模块化替代品。 React Hooks 允许您构建基于函数的组件,而不是类组件。
先决条件
要完成本教程,需要了解 React。 要了解有关 React 的更多信息,请查看 How To Code in React 系列。
分析useState()
方法
在类组件中,您可以将 React 导入 index.js
文件并创建类对象 JustAnotherCounter
的实例。 您将添加一个状态和一个函数来更新属性 count
:
index.js
import React, { Component } from 'react'; class ScoreCounter extends Component { state = { count: 0 }; setCount = () => { this.setState({ count: this.state.count + 1 }); }; render() { return ( <div> <h1>{this.state.count}</h1> <button onClick={this.setCount}>Count Up To The Moon</button> </div> ); } }
在您的 render
生命周期方法中,您将返回 state 中保存的值和一个通过每次单击调用您的函数的按钮。
让我们将您的 ScoreCounter
类组件作为功能组件进行比较。
使用 React Hooks,您可以用更少的代码行将您的状态和生命周期方法压缩到 index.js
文件中的功能组件中。 将 useState
导入解构对象:
[label index.js] import React, { useState } from 'react'; function ScoreCounter() { const [count, setCount] = useState(0); return ( <div> <h1>{count}</h1> <button onClick={() => setCount(count + 1)}>Count Up To The Moon</button> </div> ); }
useState()
方法将您的状态对象解构为一个数组,并为其元素分配调用 hook 的值。 第一个元素是状态,而第二个元素是作为 .setState()
方法运行的函数。 您传递给 useState()
方法的参数充当初始状态值,这里的数字 0
作为您的计数器。 您可以传入任何数据类型,例如数组、对象、字符串和数字作为初始状态值。
每次单击按钮时,setCount()
函数都会将您的状态作为参数传递,该参数递增 1
。
现在,您的 ScoreCounter
功能组件支持的语法较少,有利于代码的可读性。
您还可以在同一个函数中多次使用 useState()
方法。 在您的 index.js
文件中,导入 useState
并声明功能组件 Login
:
index.js
import React, { useState } from 'react'; function Login() { const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); return ( <div className="login"> <form> <label> Username: <input value={username} onChange={event => setUsername(event.target.value)}/> <br /> Password: <input value={password} onChange={event => setPassword(event.target.value)}/> </label> <button>Submit</button> </form> </div> ); }
Login
功能组件多次使用useState()
方法在表单中定义和设置用户名和密码,并概述了每个input
字段的逻辑。
了解了 useState()
之后,我们再来看看其他的 React Hook 方法。
使用 useEffect()
方法
React Hooks 引入了 useEffect()
方法来替换类组件的生命周期方法 componentDidMount
、componentDidUpdate
和 componentWillUnmount
。 该方法还允许在您的功能组件中产生副作用,例如更改文档对象模型中的内容和获取数据。 useEffect()
将在每个组件渲染后运行。
让我们将类的生命周期方法调用与功能组件进行比较。
在 index.js
文件中,将 useEffect
导入 ScoreCounter
组件:
[label index.js] import React, { useState, useEffect } from 'react'; function ScoreCounter() { const [count, setCount] = useState(0); useEffect(() => { console.log(count); document.title = `Your new score is ${count}`; }); return ( <div> <h1>{count}</h1> <button onClick={() => setCount(count + 1)}>Count Up To The Moon</button> </div> ); }
在这里,useEffect()
产生登录控制台以检查 count
中的初始状态值并更新文档对象模型的副作用。
由于 useEffect()
每次组件渲染时都会运行,因此您可以设置第二个参数,一个数组来存储每个实例并在值发生更改时调用该方法。
在 index.js
文件中,将一个空数组作为 useEffect()
方法的第二个参数应用:
[label index.js] import React, { useState, useEffect } from 'react'; function ScoreCounter() { const [count, setCount] = useState(0); useEffect(() => { console.log(count); document.title = `Your new score is ${count}`; }, []); }
每次渲染到 ScoreCounter
组件时,useEffect()
方法会将 count
的每个实例存储在数组中,如果值与之前的调用不同,则更新组件。 在一次调用中,useEffect()
结合了 componentDidMount
和 componentDidUpdate
生命周期方法中的功能。
要模拟 componentWillUnmount
生命周期方法,请在 index.js
文件的 useEffect()
方法中返回一个函数:
[label index.js] import React, { useState, useEffect } from 'react'; function ScoreCounter() { const [count, setCount] = useState(0); useEffect(() => { console.log(count); document.title = `Your new score is ${count}`; return () => console.log(`Component is unmounted`); }, []); }
通过声明并返回一个匿名函数,useEffect()
方法在一次调用中卸载组件,这里使用 console.log
来检查其状态。
要获取数据,请在 useEffect()
中传递 fetch 以从外部 API 获取信息。
在您的 index.js
文件中,导入 useState
和 useEffect
。 声明一个 GitHubUsers
函数组件,并在 useEffect
的主体内传入 fetch
:
index.js
import React, { useState, useEffect } from 'react'; function GitHubUsers() { const [user, setUsers] = useState([]); useEffect(() => { fetch('https://api.github.com/users') .then(response => response.json()) .then(data => { setUsers(data); // set users in state }); }, []);
注意第二个参数设置为一个空数组。 这是为了通知useEffect()
运行一次。 useEffect()
方法将调用 fetch
来调用 GitHub API 并将响应设置为 JSON 对象。
调用成功后,在您的 GitHubUsers
组件中包含一个返回语句,以遍历数据并输出 GitHub 用户信息:
index.js
return ( <div className="section"> {users.map(user => ( <div key={user.id} className="card"> <h5>{user.login}</h5> </div> ))} </div> ); }
useEffect()
方法在一次调用中获取类组件的所有三个生命周期方法中的功能,以登录控制台、更新文档对象模型并从外部 API 获取数据。
结论
useState()
和 useEffect()
方法是对 React 库的强大补充。 现在使用 React Hooks,您可以在更短的代码行中使用状态和生命周期方法最大化您的功能组件。
有关 React Hooks 的更多信息,请查看 How To Manage State with Hooks on React Components 文章。