useEffect的具体使用
react 中useEffect 是一个很常用的hooks,可以用于处理一些副作用,比如日志打印,请求发送,错误处理和上报等。定义如下:
function useEffect(effect: EffectCallback, deps?: DependencyList): void;
简单的demo实例如下:
const [cnt, setCnt] = useState(1);
useEffect(() => {
console.log("cnt changed");
}, [cnt]);
注意细节和常见问题
- deps 依赖数组中的变量,是有要求的,并非所有变量的值变化了,副作用都会重新执行。
一般,依赖的变量,要么是useState或者useReducer方法解构出的变量,要么就是useRef方法解构出来的变量(需要搭配useUpdate 刷新一起使用),普通的常量并不会起作用。具体例子如下。
import React, { useEffect } from "react";
import { useState } from "react";
import { Button } from 'antd';
import { useReducer } from "react";
import { useRef } from "react";
export default () => {
const [cnt, setCnt] = useState(1);
// useRef 如果传递函数,组件更新之后,函数会重新执行
// 如果传递的是值,则组件更新,对应的值不会被初始化执行
const cntRef = useRef(1);
const [obj, refresh] = useState({});
let count = 0;
const [state, dispatchState] = useReducer((state, action) => {
switch(action.type) {
case 'increment':
return state + 1;
case 'decrement':
return state - 1;
default:
return state;
};
return state;
}, 0);
console.log('count:', count);
useEffect(() => {
console.log("cnt changed");
}, [count]);
useEffect(() => {
console.log('useReducer 结构的响应式变量变化了后,useEffect可以触发');
}, [state]);
useEffect(() => {
console.log('useEffect能捕捉到ref中的值的变化');
}, [cntRef.current]);
const udpateCntRef = () => {
cntRef.current++;
refresh({});
};
const changeCnt = () => {
// setCnt(cnt => cnt +1);
count++;
console.log('count:', count);
};
return (
<div>
<h1>Success</h1>
<h2>state: {state}</h2>
<Button onClick={() => changeCnt()}>更改cnt的值</Button>
<Button onClick={() => dispatchState({
type: 'increment',
})}>dispatch触发更新</Button>
<Button onClick={() =>udpateCntRef() }>ref值变化</Button>
</div>
);
};
- useEffect 存在闭包陷阱问题
useEffect 回调函数中,使用的变量,与依赖数组中的变量是有关联的。如果依赖数组中的变量为空,则回调函数中,引用的变量为初始化时候的变量。
const [count, setCount] = useState(0);
// 无论SetCount 怎么修改count 值,这里count 值,始终是0
useEffect(() => {
console.log("cnt changed", count);
}, []);