React Hooks 是 React 16.8 中引入的新特性,用于在函数组件中添加 state 以及其他功能。使用 Hooks 可以避免代码冗余、提高代码可读性和可维护性。本文将详细介绍 React Hooks 的使用,以及如何使用它来优化前端开发。
useState Hook
useState Hook 是 React Hooks 中的第一个钩子。它在函数组件中添加了 state 的功能,用法如下:
const [state, setState] = useState(initialState);
useState 的第一个参数是初始 state 值,第二个参数是一个函数,用于更新 state 值。useState 返回的值是一个数组,第一个元素是当前的 state,第二个元素是用于更新 state 的函数。
下面是一个简单的例子:
// www.javascriptcn.com code example
import React, { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
}
export default Counter;在这个例子中,我们使用 useState 来添加了一个计数器功能。当用户点击按钮时,我们使用 setCount 函数将 count 的值加 1,从而更新视图。
useEffect Hook
useEffect Hook 能够让我们在 function 组件中使用类似与 componentDidMount、componentDidUpdate 和 componentWillUnmount 的效果。它可以在渲染完成后执行一些操作,比如:
- 发起异步请求
- 订阅或取消订阅事件
- 更新 DOM 元素等等
例如,使用 useEffect 与 Fetch API 发起异步请求:
// www.javascriptcn.com code example
import React, { useState, useEffect } from 'react';
function FetchExample() {
const [data, setData] = useState([]);
useEffect(() => {
const fetchData = async () => {
const result = await fetch('https://jsonplaceholder.typicode.com/todos/');
const json = await result.json();
setData(json);
};
fetchData();
}, []);
return (
<ul>
{data.map(item => (
<li key={item.id}>{item.title}</li>
))}
</ul>
);
}
export default FetchExample;这个例子中,我们使用 useState 来保存由 fetch 得到的数据,并使用 useEffect 进行一次性数据获取。当组件首次渲染之后,我们会发起一个异步请求并将得到的数据保存到 state 中。
useContext Hook
useContext Hook 可以让我们在 function 组件中 使用 context 。
// www.javascriptcn.com code example
import React, { useContext } from 'react';
const MyContext = React.createContext();
function MyComponent() {
const value = useContext(MyContext);
return <div>{value}</div>;
}
export default MyComponent;在这个例子中,我们使用 createContext 创建一个 MyContext 对象,然后使用 useContext 获取 MyContext 的值。
使用 useReducer 优化状态管理
需要有一个简单的 Demo 来展示这段代码的用途
在大型应用程序中,使用 useState 存储全局状态可能会变得非常混乱和难以维护。这时就需要 useReducer 优化状态管理。
useReducer 情况下的 todo demo,当 state 比较复杂时,useReducer 可以作为一种更灵活的方式优化 React 的状态管理:
// www.javascriptcn.com code example
import React, { useReducer } from "react";
const initialState = {
text: "",
todos: []
};
function reducer(state, action) {
switch (action.type) {
case "set_text":
return {
...state,
text: action.text
};
case "add_todo":
return {
...state,
text: "",
todos: [...state.todos, { text: state.text }]
};
case "delete_todo":
return {
...state,
todos: [
...state.todos.slice(0, action.index),
...state.todos.slice(action.index + 1)
]
};
default:
return state;
}
}
function TodoList() {
const [{ text, todos }, dispatch] = useReducer(reducer, initialState);
function handleSubmit(event) {
event.preventDefault();
dispatch({ type: "add_todo" });
}
function handleDelete(index) {
dispatch({ type: "delete_todo", index });
}
return (
<div>
<form onSubmit={handleSubmit}>
<input
type="text"
value={text}
onChange={event =>
dispatch({ type: "set_text", text: event.target.value })
}
/>
<button type="submit">Add todo</button>
</form>
<ul>
{todos.map((todo, index) => (
<li key={index}>
<span>{todo.text}</span>
<button onClick={() => handleDelete(index)}>X</button>
</li>
))}
</ul>
</div>
);
}
export default TodoList;在这个例子中,我们使用 useReducer 执行 todos 的一系列加、删、改操作。每个操作都发送一个 Action,并根据 Reducer 中的处理逻辑更新状态。
自定义 Hooks
自定义 Hooks 可以让我们将一些常用的逻辑功能抽象出来,将其从组件中抽离出来,使得代码更简洁、可复用性更高。
例如,我们可以创建 getAuthedUser 的自定义 Hooks:
// www.javascriptcn.com code example
import axios from "axios";
import { useEffect, useState } from "react";
function useAuthedUser() {
const [user, setUser] = useState(null);
useEffect(() => {
axios
.get("/api/me")
.then(res => setUser(res.data))
.catch(error => console.log(error));
}, []);
return user;
}
export default useAuthedUser;然后就可以在其他组件中使用这个 Hook:
// www.javascriptcn.com code example
import React from "react";
import useAuthedUser from "./useAuthedUser";
function UserDashboard() {
const user = useAuthedUser();
return (
<div>
{user && (
<>
<h1>Hello, {user.name}!</h1>
<p>Your email is {user.email}</p>
</>
)}
</div>
);
}
export default UserDashboard;Hooks 的注意事项
useState 和 useEffect 是最常使用的 Hook,我们需要注意它们的用法。useState 应该只用于储存组件级别的 state,而不是共享 state,且在它们嵌套当中不应该有副作用。useEffect 应该总是返回一个 cleanup 函数,以避免无意中遗留的副作用。
在函数组件中使用 Hooks 非常方便,但是不能在条件语句或循环语句当中使用。
useState 和 useReducer 中的 state 初始化只会在组件刚刚加载时执行一次,并不会重复执行。如果需要重复执行,需要将 state 放在 useEffect 中。
Hooks 只能在函数组件中使用,不能在 class 组件中使用。
本文介绍了 React Hooks 的使用和应用。React Hooks 使得开发中的代码更加简洁、可读、可维护。在实践中,我们应该使用自定义 Hooks 将常用的逻辑抽象出来,以便于复用和管理。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67cfdd6ae46428fe9ec0ebe6