每个函数里面的Hook结构
export type Hook = {
memoizedState:any,
baseState:any,
baseQueue:Update<any,any> | null,
queue:any,
next:Hook | null //下一个Hook
}
具体应用:
目录
fiber.memoizedState(hook0).next(hook1).next(hook2).next(hook3)...
//因为其中是链式的结构所以在使用Hook的时候不用在回调和if 条件以及循环中使用
//也不可以在子函数里面调用hook(可以自定义Hook来使用)
Hooks 使用
//每次调用setCount count累加 2 初始值是0
const [count , setCount] = useReducer((count:number)=>{return count+2;},0)
//每次调用setCount count累加 2 初始值是1
const [count , setCount] = useReducer((count:number)=>{return count+2;},0,(data:number)=>{
//这个值就是 第二个参数 0
return number+1;
})
//不管 count 的值有没有变化,只要调用setCount 那么dom组件就会更新
使用 useReducer
const [count , dispatch] = useReducer((state:number,action:number)=>{
return action;
},0)
const [count2 , setCount2] = useState<number>(5);
//调用setCount2 count2 赋值为50
setCount2(50);
//多次调用setCount2 值没有变化 dom组件不会更新
注:
setCount2(50); 第一次调用 dom更新
setCount2(50); 第二次调用 dom 更新 react 记录当前值
setCount2(50); 第三次调用 dom 不会更新
... 后面调用 dom都不会更新
使用 useState
1.setCount2(50);
2.setCount2(()=>50);
了解了一下感觉和 redux 差不多 用起来还麻烦
// redux 核心就是 useContext + useReducer
//该方法每次dom刷新的时候都会执行(包括第一次渲染的时候)
useEffect(()=>{
console.log(1)
})
//arguments 更新时候调用
useEffect(()=>{
},[arguments]);
// 初始化执行一次
useEffect(()=>{
},[]);
// 这里可以用来取消监听内容
useEffect(()=>{
console.log("开始监听")
return ()=>{
console.log("取消监听");
}
},[count])
注:监听执行顺序
1.组件第一次执行时候
打印 开始监听
2.count 更新时候
打印 取消监听
打印 开始监听
//使用useEffect 实现生命周期
1.首次渲染时候
useEffect(()=>{
},[])
2.组件卸载时候
useEffect(()=>{
return ()=>{}
},[])
3.监听数据变化
useEffect(()=>{
},[监听数据1,监听数据2]);
let a = 0;
//接收两个参数
//b() 不管执行多少次 a 都等于1
let b = useCallback(()=>{
a++
},[])
React.memo
//作用 当组件props没有更新时,会缓存改组件(这样父组件更新的时候子组件不会更新)
cosnt Child = React.memo(funciton(){
return (
<div>Child 我不会进行没必要的更新呦</div>
)
});
结合使用
//不使用的情况 传参数
function A(){
const [count ,setCount] = uesState(1);
function a(){
setCount(count++);
}
return (
<div onClick={a}>{count}</div>
<B></B>
);
}
function B(){
console.log('count更新的时候,我也会打印')
return <div></div>;
}
//不使用的情况 但是传参的情况
function A(){
const [count ,setCount] = uesState(1);
function a(){
setCount(count++);
}
return (
<div onClick={a}>{count}</div>
<B onA={a}></B>
);
}
function B(){
console.log('count更新的时候,我也会打印');
return <div></div>;
}
//使用 React.memo的情况 他还是会打印
function A(){
const [count ,setCount] = uesState(1);
function a(){
setCount(count++);
}
return (
<div onClick={a}>{count}</div>
<B onA={a}></B>
);
}
const B = React.memo(function B(){
console.log('count更新的时候,我也会打印');
return <div></div>;
})
注:
因为A组件每次更新的时候都重新创建了a() 方法 所以 B组件会更新
//使用 React.memo的情况 + useCallback
function A(){
const [count ,setCount] = uesState(1);
count a = uesCallback(function a(){
setCount(count++);
},[])
return (
<>
<div onClick={a}>{count}</div>
<B onA={a}></B>
</>
);
}
const B = React.memo(function B(){
console.log('count更新的时候,我不会打印');
return <div></div>;
});
6.#### useMemo应用 和 useMemo 与 useCallback区别
//接收两个参数
const value = useMemo(()=>{
return 1;
},[a,b]);
//useMemo 与 useCallback区别
1.useMemo 传入的函数必须要有返回值
2.useMemo 只能声明在函数式组件内部【React.memo 在子组件外部包裹】
使用
const c = useMemo(()=>{
//a和b没有更新的时候就算父组件更新 他也不会触发
return a + c;// 也可以返回 dom组件
},[a,b]);
注
a和b更新的时候返回更新c的值(本操作可以更新dom)
o 传入的函数必须要有返回值
2.useMemo 只能声明在函数式组件内部【React.memo 在子组件外部包裹】
使用
const c = useMemo(()=>{
//a和b没有更新的时候就算父组件更新 他也不会触发
return a + c;// 也可以返回 dom组件
},[a,b]);
注
a和b更新的时候返回更新c的值(本操作可以更新dom)