一、useState + useReducer

  1. const ReactModel = ()=>{
  2. const [n,setN] = useState(1)
  3. const onClick = ()=>{
  4. setN(n+1)
  5. }
  6. return <div onClick={onClick}>{n}</div>
  7. }
  1. const reducer = (state,action)=>{
  2. switch (action.type){
  3. case 'setN':{
  4. return {
  5. ...state,
  6. n: action.n
  7. }
  8. }
  9. }
  10. }
  11. const ReactModel = ()=>{
  12. const [state,dispatch] = useReducer(reducer,initialState)
  13. const onClick = ()=>{
  14. dispatch({type:'setN',n:state.n+1})
  15. }
  16. return <div onClick={onClick}>{n}</div>
  17. }

二、useEffect + useLayoutEffect

  1. const ReactModel = ()=>{
  2. useEffect(()=>{
  3. console.log(1)
  4. return ()=>{
  5. console.log(2)
  6. }
  7. })
  8. }
  1. const ReactModel = ()=>{
  2. useEffectLayout(()=>{
  3. console.log(1)
  4. return ()=>{
  5. console.log(2)
  6. }
  7. })
  8. }

三、memo + useMemo/useCallback

  1. const ReactModel = ()=>{
  2. const [n,setN] = useState(1)
  3. const onClick = useMemo(()=>{
  4. return ()=>{
  5. console.log(n)
  6. }
  7. },[n])
  8. return <ReactModel2 onClick={onClick} n={n} />
  9. }
  10. const ReactModel2 = React.memo((props)=>{
  11. return <div onClick={props.onClick}>{props.n}</div>
  12. })
  1. const ReactModel = ()=>{
  2. const [n,setN] = useState(1)
  3. const onClick = useCallback(()=>{
  4. console.log(n)
  5. },[n])
  6. return <div onClick={onClick}>{n}</div>
  7. }

四、useRef、forwardRef、useImperativeHandle

  1. const ReactModel = ()=>{
  2. const nRef = useRef(1)
  3. const onClick = ()=>{
  4. console.log(nRef.current)
  5. nRef.current++
  6. }
  7. return <div onClick={onClick}>按钮<div>
  8. }
  1. const ReactModel = ()=>{
  2. const buttonRef = useRef(null)
  3. return <Button ref={button}>按钮</Button>
  4. }
  5. const Button = React.forwardRef((props,ref)=>{
  6. return <button ref={ref} {...props}>
  7. })
  1. const Button = React.forwardRef((props,ref)=>{
  2. const realButton = createRef(null)
  3. useImperativeHandle(ref,()=>({
  4. x: ()=>{
  5. realButton.current.remove()
  6. }
  7. }))
  8. })
  9. // 应该叫 setRef

useRef

  • 目的
    • 如果你需要一个值,在组件不断 render 时保持不变
    • 初始化:const count = useRef(0)
    • 读取:count.current
    • 为什么需要 current?
    • 为了保证两次 useRef 是同一个值
  • 延伸
    • 看看 Vue3 的 ref
    • 初始化 const count = ref(0)
    • 读取 count.value
    • 不同点:当 count.value 变化时,Vue3 会自动 render

五、自定义 Hooks

封装自定义操作

  1. const useList = ()=>{
  2. const [list,setList] = useState(null)
  3. useEffect(()=>{
  4. ajax('/list').then(list=>{
  5. setList(list)
  6. })
  7. },[])
  8. return {
  9. list,
  10. setList
  11. }
  12. }

「@浪里淘沙的小法师」