Ask yourself a few more whys every day, and you will always get unexpected results. The growth path of a rookie Xiaobai (copyer)
1. Asynchronous useEffect (custom hook)
// 定义
function useAsyncEffect(effect: () => Promise<void | (() => void)>, dependencies?: any[]) {
return useEffect(() => {
const cleanupPromise = effect()
return () => {
cleanupPromise.then(cleanup => cleanup && cleanup()) } },
dependencies)
}
// 使用
useAsyncEffect(async () => {
const count = await fetchData() setCount(count) }, [fetchData])
2. The combination of useCallback and useEffect
When resolving the variable change, then retrigger the function
// 定义变量
const [num, setNum] = useState(0)
// 一个函数依赖变量请求
const query = React.useCallback(() => {
console.log(num)
}, [num])
// 改变变量
const changeNum = () => {
setNum(2)
}
// 直接监听函数作为变量
React.useEffect(() => {
query()
}, [query])
query
function, as long as num changes, a new function will be generated and it will be retriggereduseEffect
3. Batch update of function components
// 实例1
const App = () => {
const [list, setList] = useState(null)
const [info, setInfo] = useState(null)
const btn = async () => {
setList([])
setInfo({
})
}
React.useEffect(() => {
console.log(111);
})
return (
<div style={
{
padding: '40px'}}>
<Button onClick={
btn}>点击</Button>
</div>
)
}
// 点击按钮的过程中,会触发两次render函数(初始化一次, 修改的state的批量跟新一次)
// 实例2
const App = () => {
const [list, setList] = useState(null)
const [info, setInfo] = useState(null)
const btn = async () => {
setTimeout(() => {
setList([])
setInfo({
})
}, 0)
}
React.useEffect(() => {
console.log(111);
})
return (
<div style={
{
padding: '40px'}}>
<Button onClick={
btn}>点击</Button>
</div>
)
}
//如果是异步的, 点击按钮的过程中,会触发三次render函数(初始化一次, 批量更新被破坏,两次修改state,就会触发两次)
So in the above process, if it is asynchronous, it will be triggered once more, and there will be a waste of performance, so how to solve it?
// 解决方式一 合并成一个对象(如果简单可以使用)
const [info, setInfo] = useState({
list, [], info:{
}})
// 解决方式二 使用react-dom中的 一个函数 手动批量更新
import {
unstable_batchedUpdates } from 'react-dom'
setTimeout(() => {
unstable_batchedUpdates(() =>{
setList([])
setInfo({
})
})
}, 0)
// 针对类组件也是一样的
4. ts write custom hooks
// 形式一
// 定义
import {
useState, useCallback } from 'react'
interface Action<T> {
getData: () => T;
setData: (value: T) => void;
}
type IReturn<T> = [T, Action<T>]
function useData<T>(defaultValue: T): IReturn<T> {
const [state, setState] = useState<T>(defaultValue)
const actionData = useMemo(() => {
const getData = () => state
const setData = (value: T) => setState(value)
return {
getData,
setData
}
}, [])
return [state, actionData]
}
export default useData
// 使用
const [data1, setData1] = useData<string>(321)
// setData1是一个对象
// 方式二:
type IReturn<T> = [T, (value: T) => void]
function useData<T>(defaultValue: T): IReturn<T> {
const [state, setState] = useState<T>(defaultValue)
const actionData = useCallback((value: T) => {
setState(value)
}, [])
return [state, actionData]
}
export default useData
// 使用
const [data1, setData1] = useData<string>(321)
// setData1是一个函数