本教程是React Hooks系统教程中的一部分。
React 函数组件本身不包含状态和生命周期,因此需要使用一些 Hooks (勾子)函数来实现状态保持、状态共享和传递。
useState
可以通过 useState 为函数组件添加内部状态。组件会侦听 state 的状态变化并重新 render 渲染组件。下面我们使用 useState 创建了一个计数器,文件名为 ExampleState.js
此示例实现单击按钮,增加计数。
import React, { useState } from "react";
export function ExampleState() {
const [count, setCount] = useState(0);
return (
<div>
<hr/>
<h1>useState: {count}</h1>
<button onClick={()=>{ setCount(count+1) }}>Click me</button>
</div>
)
}
const [count, setCount] = useState(0); 代表 count 初始值为 0, 通过 setCount 改变 count 的值。
useEffect
useEffect 可以用来侦听状态变化,并执行相应逻辑。
无参数
当 useEffect 无参数使用时,会侦听当前组件所有状态的变化,因此不带参数的 useEffect 函数中不能使用useState方法来改变state,否则会触发无限循环:
下面的例子,当点击 Click me 按钮时,都会执行 useEffect 中的函数,改变 effect 显示值。
import React, { useState, useEffect } from "react";
let effect = 0;
export function ExampleEffect() {
const [count, setCount] = useState(0);
useEffect(()=>{
document.getElementById('effect').innerText = ++effect;
})
return (
<div>
<hr/>
<h1>useEffect 无参数 effect:<b id="effect"></b> count: {count}</h1>
<button onClick={()=>{ setCount(count+1) }}>Click me</button>
</div>
)
}
并且effect的值始终比count多1,因为useEffect第一次渲染时也会执行,效果如下图所示:
带参数
当 useEffect 带参数时,参数的变化才会触发 useEffect 的执行。此时可使用 useState。
import React, { useState, useEffect } from "react";
export function ExampleEffectArgs() {
const [count, setCount] = useState(0);
const [effect, setEffect] = useState(0);
useEffect(()=>{
setEffect(effect+1);
}, [count])
return (
<div>
<hr/>
<h1>useEffect 带参数 effect:{effect} count: {count}</h1>
<button onClick={()=>{ setCount(count+1) }}>Click me</button>
</div>
)
}
这段代码的效果与上面的例子相同。
空参数
当 useEffect 传入空参数 [] 时,只有当第一次渲染(mount) 和不渲染(unmount)时执行。
完整示例: