React之hooks
官方内置 hooks
useState
在函数组件中管理数据状态
基本数据类型
import React from 'react'
export function App(props) {
const [count, setCount] = React.useState(0)
return (
<div className='App'>
<div>{count}</div>
<button onClick={() => setCount(() => count + 1)}>add</button>
<button onClick={() => setCount(count + 1)}>add</button>
<button onClick={() => setCount(c => c + 1)}>add</button>
</div>
)
}
主要注意的点是 setCount 可以传入相应数值或匿名函数,如上所示的都是可以实现对 count+1
对象
这里主要针对复杂类型(数组,对象),示例:
import * as React from 'react'
export default function App(props) {
type User = {
name: string
age: number
}
const [user, setUser] = React.useState<User>({
name: 'kuizuo',
age: 20,
})
return (
<div className="App">
<div>{user.name}</div>
<div>{user.age}</div>
<button
onClick={() => {
setUser((obj) => ({
...obj,
name: '愧怍',
}))
}}
>
set name as 愧怍
</button>
</div>
)
}
数组
import * as React from 'react'
export default function App(props) {
const [arr, setArr] = React.useState(['code', 'eat', 'sleep'])
return (
<div className="App">
{arr.map((a) => (
<div>{a}</div>
))}
<button
onClick={() => {
setArr((arr) => [...arr, '123'])
}}
>
append
</button>
</div>
)
}
useState 对于复杂类型而言,尤其是在赋值操作是比较麻烦的。没办法,因为需要更改状态就需要调用 setState 方法,而 setState 方法需要传入最终完整的数据。
对于对象而言,可以考虑使用 react use 的 useMap,对于数组而言,可以考虑使用 react use 的 useList。(其实都是对 setState 进行一定的封装)
useEffect
useEffect 可以让你在函数组件中执行副作用操作
副作用是指一段和当前执行结果无关的代码,常用的副作用操作如数据获取、设 置订阅、手动更改 React 组件中的 DOM。
useEffect 可以接收两个参数,代码如下:
useEffect(callback, dependencies)
第一个参数是要执行的函数 callback,第二个参数是可选的依赖项数组 dependencies。
以下是一些示例:
import * as React,{} from 'react'
export default function App() {
const [count, setCount] = React.useState(0)
React.useEffect(()=>{
console.log(count)
})
return <div onClick={() => setCount(count+1)}>{count}</div>
}
每当 count 发生变化后,useEffect 副作用函数就会输出 count,由于没传入 dependencies 数组, 则每次 render 后执行
如果第二个参数给空数组的话,只会在第一次加载组件时执行,通常可用于首次数据请求。
import * as React from 'react'
export default function App() {
const [data, setData] = React.useState('')
React.useEffect(() => {
async function fetchData() {
const data = await (await fetch('https://api.kuizuo.cn/api/one')).text()
console.log(data)
setData(data)
}
fetchData()
}, [])
return <div>{data}</div>
}
此外 componentWillUnmount 生命周期也可在 useEffect 中执行。
import * as React from 'react'
export default function App() {
const [data, setData] = React.useState('')
React.useEffect(() => {
// Update the document title using the browser API
document.title = `You clicked ${count} times`
return () => {
// 可用于做清除,相当于 class 组件的 componentWillUnmount
}
}, [count]) // 指定依赖项为 count,在 count 更新时执行该副作用
return <div onClick={() => setCount(count+1)}>{count}</div>
}
小总结
useEffect 提供了四种执行副作用的时机:
- 每次 render 后执行:不提供第二个依赖项参数。比如
useEffect(() => {})
- 仅第一次 render 后执行:提供一个空数组作为依赖项。比如
useEffect(() => {}, [])
- 第一次以及依赖项发生变化后执行:提供依赖项数组。比如
useEffect(() => {}, [deps])
- 组件 unmount 后执行:返回一个回调函数。比如
useEffect(() => { return () => {} }, [])