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
  • 相关阅读:
    【转】sql 如何设计数据库表实现完整的RBAC(基于角色权限控制)
    【转】windows自带终止进程的超强命令
    【源码】 gridview 里使用checkbox
    【转】调用 开始 运行 直接执行命令
    【源码】DropDownList绑定数据
    C++ 编译器数据类型差异
    Flash 中将不透明的 Bitmap 透明化处理
    使用命令行切换IP地址
    MKV 高清视频文件分解与封装和音频编码的转换
    Visual Studio 2010 C++ 用户属性设置
  • 原文地址:https://www.cnblogs.com/MDGE/p/13847836.html
Copyright © 2011-2022 走看看