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();
}
}