Hook
概览
Hook 是 React 16.8 版本引入的一种新特性,它允许我们在函数组件中使用 state 和其他的 React 特性,而不需要编写 class。更加灵活和强大,提高了代码复用性。
Hooks 的底层实现主要依赖于 React 的 Fiber 架构 和 JavaScript 的闭包。闭包可以保存 Hook 的状态和内部变量。
可以使用内置的 Hook 或自定义 Hook。
推荐安装 eslint-plugin-react-hooks
Hook 规则
- 只能在函数组件的最顶层调用 Hook
- 不能在循环、条件判断或嵌套函数中调用 Hook
- 不能在普通的 js 函数中调用 Hook
useState
useState()
用于在函数组件中添加状态。接受一个初始值作为参数,返回一个由当前状态和更新状态的函数组成的数组,当调用这个函数去修改状态时,会触发组件重新渲染。
useState 针对每个组件实例都有自己的状态,不会共享状态。
import { useState } from 'react';
export default function Home() {
const [count, setCount] = useState(0);
const decrement = () => {
setCount(prev => prev + 1);
};
return (
<div>
<p>{count}</p>
<button onClick={decrement}>decrement</button>
<button onClick={() => setCount(count - 1)}>increment</button>
</div>
);
}
如果状态是对象或数组,应该替换状态而不是更改现有对象
const initialState = [
{ id: 0, title: 'a', done: true },
{ id: 1, title: 'b', done: false },
{ id: 2, title: 'c', done: false }
];
const [list, setList] = useState(initialState);
// 向数组中添加元素
setList([...list, { id: 3, title: 'd', done: false }]);
// 删除数组中的某个元素
setList(list.filter(item => item.id !== id));
// 更新数组中的某个元素
setList(
list.map(item => {
if (item.id === newItem.id) {
return newItem;
} else {
return item;
}
})
);
const [state, setState] = useState({ id: 0, count: 0 });
// 更改对象状态的值,不能直接使用 state.count = 1
setState({ ...state, count: 1 });
1、为什么要使用 useState,直接声明变量不行吗?
假设直接声明变量,点击按钮后能看到 count 打印出来的值是变了,但是页面却没有变化。因为没有触发组件重新渲染,详见 React 渲染原理
export default function Home() {
let count = 0;
const increase = () => {
count = count + 1;
console.log(count);
};
return (
<div>
<p>{count}</p>
<button onClick={increase}>click</button>
</div>
);
}