zoukankan      html  css  js  c++  java
  • useReducer源码实现

    要知道useReducer是useState的语法糖

    function useState (initial){

      return  useReducer(null,initial)

    }

    function useReducer(reducer,initialState){
      hookStates[hookIndex] = hookStates[hookIndex]||initialState;
      let currentIndex = hookIndex;
      function dispatch(action){
        hookStates[currentIndex] = reducer?reducer(hookStates[currentIndex],action):action;
        console.log(hookStates[currentIndex])
        render();
      }
      return [hookStates[hookIndex++],dispatch];
    }

    看组件里具体写了什么

    function Counter1(){
      let [number,setNumber] = useState(0);
      return (
        <div>
          <p>{number}</p>
          <button onClick={()=>setNumber(number+1)}>+</button>
        </div>
      )
    }
    function Counter2(){
      //reducer 初始状态
      let [state,dispatch] = useReducer(counterReducer,0);
      return (
        <div>
          <p>{state}</p>
          <button onClick={()=>dispatch({type:'add'})}>+</button>
        </div>
      )
    }
    function render(){
      hookIndex=0;
      ReactDOM.render(
        <div><Counter1/><hr/><Counter2/></div>,
        document.getElementById('root')
      );
    }
    render();
    useState这里不用说,因为useReducer会了,useState也就会了
    我们在Counter2组件中点击+,会触发useReducer函数里面的dispatch方法,这里的dispatch方法里面有action   
     

    如果用useReducer那么一定是两个参数啊,第一个参数是传统redux中的reducer函数,看代码

    function useReducer(reducer,initialState){
      hookStates[hookIndex] = hookStates[hookIndex]||initialState;
      let currentIndex = hookIndex;
      function dispatch(action){
        hookStates[currentIndex] = reducer?reducer(hookStates[currentIndex],action):action;
        console.log(hookStates[currentIndex])
        render();
      }
      return [hookStates[hookIndex++],dispatch];
    }
    function useState(initialState){
      return useReducer(null,initialState);
    }
    function counterReducer(state,action){
       switch(action.type){
         case 'add':
           return state+1;
         default:
           return state;  
       }
    }
    我们调用
    <button onClick={()=>dispatch({type:'add'})}>+</button>
    useReducer函数里的dispatch函数有参数 而且reducer也是存在的所以 走counterReducer ,render渲染
     
    针对上面的hooks问题在工作中也遇到过 三个echarts 图点击上面的放大按钮,点击之后单独弹出一个框里面是绘制好的echart    
    我们基于这个场景  肯定是有问题的,原因在于dom没有渲染出来就调用了echarts方法。我们用setTimeout可以模拟异步去解决
    本文中我们选择:我们选择将  
    import React from 'react';

    export default function useForceUpdate() {
      const [, forceUpdate] = React.useReducer(x => x + 1, 0);
      return forceUpdate;
    }
    其实这个useForceUpdate的方法在于执行之后就可以渲染。渲染就可以  重新进入useEffect里面。也就是重新去绘制echarts
  • 相关阅读:
    USACO 2021 US Open
    【UR #20】跳蚤电话
    省选前的做题记录
    PE444
    杂题
    CF1190E
    gym100299E
    杂题
    2021 5 10 团队博客
    2021 5 9 团队博客
  • 原文地址:https://www.cnblogs.com/MDGE/p/13847836.html
Copyright © 2011-2022 走看看