常用hooks归纳

useMemo

1 用作优化当前组件 做数据缓存 防止重绘

function Example() {
    const [count, setCount] = useState(1);
    const [val, setValue] = useState('');
 
    const getNum = useMemo(() => {
        return Array.from({length: count * 100}, (v, i) => i).reduce((a, b) => a+b)
    }, [count])
 
    return <div>
        <h4>总和:{getNum}</h4>
        <div>
            <button onClick={() => setCount(count + 1)}>+1</button>
            <input value={val} onChange={event => setValue(event.target.value)}/>
        </div>
    </div>;
}

2 防止子组件重绘

useCallback

function Parent() {
    const [count, setCount] = useState(1);
    const [val, setValue] = useState('');
 
    const getNum = useCallback(() => {
        return Array.from({length: count * 100}, (v, i) => i).reduce((a, b) => a+b)
    }, [count])
 
    return <div>
        <Child getNum={getNum} />
        <div>
            <button onClick={() => setCount(count + 1)}>+1</button>
            <input value={val} onChange={event => setValue(event.target.value)}/>
        </div>
    </div>;
}

const Child = React.memo(function ({ getNum }: any) {
    return <h4>总和:{getNum()}</h4>
})
useMemo第一个参数是个函数,useMemo返回第一个参数的执行结果,也就是return的值;
useCallback第一个参数也是函数,useCallback返回第一个参数,也就是个函数;

useMemo(() => fn, []) 等同于 useCallback(fn, [])

都需要子组件具备React.memo 才能对比props是否发生改变,如果没变就不重绘子组件

如果子组件没有包React.memo那么就可以这样写
{
useMemo(() => {
return <Child getNum={getNum} />
}, [count])
}

useHistory useLocation

import { useLocation, useHistory } from 'react-router-dom'

const history = useHistory()
const location = useLocation()

// 传参
history.push({
      pathname: '/service/contractPreview',
      state: { contractViewUrl: 'xxxxx' },
})

// 取值
location.state.contractViewUrl

// 标签传参
<Link
   to={{
         pathname: `/service/contractPreview`,
         state: { contractViewUrl: 'xxxxx' },
   }}
>
   xxx
</Link>

useReducer

import React, {FC, memo, useCallback, useContext, useMemo, useReducer, useState} from 'react'

interface IGlobalContext {
  data: string,
  dispatch: Function
}

const GlobalContext = React.createContext<IGlobalContext>({
  data: '',
  dispatch: () => {}
})

const initialState = {
  title: '首页',
  color: 'red',
  name: 'kong',
  data: {
    love: 'guanguan'
  }
}

const titleReducer = (state: any, action: {type: string, payload: any}) => {
  if( action.type === "UPDATE_TITLE_AND_COLOR") {
    return action.payload
  }else if( action.type === 'UPDATE_NAME_AND_LOVE'){
    return {
      ...state,
      name: action.payload.name,
      data: action.payload.data
    }
  }
  return state
}

// useMemo优化当前页面 缓存复杂数据 demo
const Happy: FC = () => {
  
  const [data, dispatch] = useReducer(titleReducer, initialState)

  return <div>
    <GlobalContext.Provider
      value={{
        data,
        dispatch
      }}
    >
      <SubComp />
    </GlobalContext.Provider>
  </div>
}

const SubComp: FC = () => {

  const {data, dispatch} = useContext(GlobalContext)

  const changeInfo = () => dispatch({
    type: 'UPDATE_TITLE_AND_COLOR',
    payload: {
      title: '哈哈哈',
      color: 'green'
    }
  })
  const changeInfo2 = () => dispatch({
    type: 'UPDATE_NAME_AND_LOVE',
    payload: {
      name: 'guanguan',
      data: { love: 'kong' }
    }
  })

  return <div>
    {data.title}<br /><br />
    <div style={{width: 200, height: 50, backgroundColor: data.color}}></div><br />
    <div>{data.name}</div><br />
    <div>{data?.data?.love}</div><br />
    <button onClick={()=>changeInfo()}>点击更改标题和颜色</button>
    <button onClick={()=>changeInfo2()}>点击更改名字和喜欢</button>
  </div>
}

export default Happy