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
  • 相关阅读:
    正则表达式(十四)——找出某一个网页内部的所有的邮箱
    正则表达式(十三)——分组
    正则表达式(十二)——字符串的替换
    正则表达式(十一)——find和lookingAt
    查看隐藏文件夹
    SpringBoot 热部署
    oracle dmp文件泵导入
    python -爬虫-pycrul安装问题
    阿里云https tomcat配置
    jar包下载
  • 原文地址:https://www.cnblogs.com/MDGE/p/13847836.html
Copyright © 2011-2022 走看看