React actual combat code collection (doing)

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])

queryfunction, 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是一个函数

Guess you like

Origin blog.csdn.net/James_xyf/article/details/121386789