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
  • 相关阅读:
    编译FreePascal和Lazarus
    QTreeView使用点点滴滴
    刨根问底儿 -- intVal($str) 跟 (int) $str 的运算结果有什么区别
    Qt源代码分析
    QString够绕的,分为存储(编译器)和解码(运行期),还有VS编译器的自作主张,还有QT5的变化
    C++静态变量本身可否是一个实例对象
    QT4.86写中文XML
    点击TButton后的执行OnClick和OnMouseDown两个事件的过程(其实是通过WM_COMMAND执行程序员的代码)
    Hibernate3.0中的session.find()问题
    曲线控件我一直用codeproject上的那几个(C++ 100款开源界面库)
  • 原文地址:https://www.cnblogs.com/MDGE/p/13847836.html
Copyright © 2011-2022 走看看