useCallback,useMemo源码

import React, {useState,memo,useCallback,useMemo} from 'react';
import ReactDOM from 'react-dom';
let ChildComp = ({info,changeStr})=>{
  console.log(1111111)
  return <div>
    <span>{info.str}</span>
    <button onClick={changeStr}>+++++++==</button>
  </div>
}
ChildComp = memo(ChildComp)
function ParentComp () {
    console.log('render')
    const [ count, setCount ] = useState(0)
    const [str,setCount2] = useState(99)

    let info = useMemo(()=>({str}),[str])
    let addClick = useCallback(()=>setCount2(str+1),[str])
    return (
      <div>
        <button onClick={()=>setCount(count + 1)}>点击次数:{count}</button>
        <ChildComp info={info} changeStr={addClick}/>
      </div>
    );
}
ReactDOM.render(
    <ParentComp/>,
    document.getElementById('root')
);
 
先给大家段代码,好方便回去练习
 
我们发现将
// let info = useMemo(()=>({str}),[str])注掉之后依然可以实现改变父级组件子组件不会渲染,为什么?
因为info 在useState里面存下来了,addClick也存下来了
function useCallback(callback,dependencies){
 if(hookStates[hookIndex]){//说明不是第一次,
    let [lastCallback,lastDependencies] = hookStates[hookIndex];
    //判断一下新的依赖数组中的每一项是否跟上次完全相等
    let same = dependencies.every((item,index)=>item === lastDependencies[index]);
    if(same){
      hookIndex++;
      return lastCallback;
    }else{//只要有一个依赖变量不一样的话
      hookStates[hookIndex++]=[callback,dependencies];//hookIndex=3 callback=()=>setNumber(number+1)  dependencies=[0]
      return callback;
    }
 }else{//说明是第一次渲染
  hookStates[hookIndex++]=[callback,dependencies];//hookIndex=3 callback=()=>setNumber(number+1)  dependencies=[0]
  return callback;
 }
}
function useMemo(factory,dependencies){
  if(hookStates[hookIndex]){//说明不是第一次,
     let [lastMemo,lastDependencies] = hookStates[hookIndex];
     //判断一下新的依赖数组中的每一项是否跟上次完全相等
     let same = dependencies.every((item,index)=>item === lastDependencies[index]);
     if(same){
       hookIndex++;
       return lastMemo;
     }else{//只要有一个依赖变量不一样的话
      let newMemo= factory();
      hookStates[hookIndex++]=[newMemo,dependencies];
      return newMemo;
     }
  }else{//说明是第一次渲染
    let newMemo= factory();
      hookStates[hookIndex++]=[newMemo,dependencies];
      return newMemo;
  }
 }
看到这里你是不是想到了useEffect
function useEffect(callback,dependencies){
  if(hookStates[hookIndex]){//说明不是第一次,
    let lastDependencies = hookStates[hookIndex];
    let same = dependencies.every((item,index)=>item === lastDependencies[index]);
    if(same){
      hookIndex++;
    }else{
      hookStates[hookIndex++]= dependencies;
      callback();
    }
  }else{//说明是第一次渲染
    hookStates[hookIndex++]= dependencies;
    callback();
  }
}
posted @ 2020-10-22 15:50  国服第一李师师  阅读(354)  评论(0编辑  收藏  举报