React学习#02 React组件生命周期以及useEffect
1. 内容介绍
1.1 组件生命周期
1.1.1总览
[外链图片转存中…(img-Lm3HlKL3-1681539195854)]
在代码上通过函数定义的组件生命周期不如class方法定义的清晰,学习时可以参考class定义组件的生命周期方法便于理解,但是实际使用还是推荐函数式定义+Hooks来定义组件以及控制组件的渲染,国内基于React的流行框架也已基本都转向函数式定义组件,这已经成为一个大的流行趋势。
1.1.2 代码示例(具体方法实现省略为伪代码)
class InputByClass extends React.Component<any, {value:string}>{
//构造函数
constructor(props:any) {...}
//会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。
// 返回一个对象来更新 state,如果返回 null 则不更新任何内容
static getDerivedStateFromProps(prevProps: Readonly<any>, prevState: Readonly<{ value: string }>){...}
onClick:(e:string)=>void = (e)=>{...}
//组件触发更新渲染调用 入参原state 原props
//hook类似实现 useEffect(()=>{}) 集成 componentDidUpdate+componentDidMount
componentDidUpdate(prevProps: Readonly<any>, prevState: Readonly<{ value: string }>) {...}
//组件触发更新前会调用 入参 更新后的props,state 返回boolean类型 true:更新 false:阻止更新
//不常用 可用于于父组件重新时控制渲染子组件是否渲染
//注意 hook类似实现 const Component = React.memo((props) => {组件},((prevProps, nextProps)=>{return true})); 结果返回判断相反 局限:只能判断props的更改
shouldComponentUpdate(nextProps: Readonly<any>, nextState: Readonly<{ value: string }>): boolean {...}
//组件挂载后调用,组件卸载前只会调用一次
//hook类似实现 useEffect(()=>{},[])
componentDidMount() {...}
//卸载使用 用于清除处理(更新组件时候清除上一次的影响,很好的体现了React数据单向流动的思想)
//hook类似 useEffect(()=>{return ()=>{清除函数}) useEffect一个清除函数函数 更新和卸载时react会自动调用(触发执行逻辑取决于影响的属性)
componentWillUnmount() {...}
//渲染
//类似函数式定义的ruturn(ReactNode);
render() {...}
}
1.2 useEffect
useEffect与useState一样也是React提供的官方Hooks放方法,useState实现了组件state对象的细分以及组件的更新,useEffect则可以通俗的理解为对于组件更新和渲染时候对组件的处理
1.2.1 使用
function useEffect(effect: EffectCallback, deps?: DependencyList);
1.useEffect方法有两个参数,effect为监听属性发生变化时执行的方法,deps是React框架监听的属性,当监听对象发生变化时会执行回调方法
2.useEffect可选择返回一个清除函数,会在下一次触发执行回调的时候先执行上次返回的清除函数,再执行回调,官方将其定义为清除函数,用于清除上一次的影响
!!!注意:React中对值是否发生变化判断时如果是对象类型则只比较对象地址,类似于Java的==,不会对比对象属性是否变化,如果对象属性值变化也需要触发React的更新逻辑,则需要重新创建一个新的对象,使其地址发生变化,包括useState的关于state对象的比较也是如此
1.2.2 常见的useEffect用法
1.useEffect(()=>{...},[])监听一个空数组,因为空数组的地址不会发生变化,所以只会执行一次,适用于作组件里只需要获取一次的执行方法使用,比如获取某些配置
2.useEffect(()=>{...})每次组件更新均会触发,类似于class定义组件的componentDidUpdate,适用于组件每次更新都需要获取最新消息的场景,比如获取最新的信息流
3.useEffect(()=>{...},[deps])根据deps是否发生变化(常见错误见注意)去选择执行,适用最多的场景
4.useEffect(()=>{... return ()=>{}},[deps]) 返回清除上一次更新影响的函数,常见于需要清除上次更新的某些数据的场景使用,比如表单窗口打开(组件的状态发生变化)时清除上次的数据
1.2.2代码示例
//此组件中对于value值的变化进行监听,如果value发生变化,更新的时候执行useEffect的执行方法(此案例中为打印value值)
const ChildComponent: React.FC<{ value: number }> = ({ value }) => {
useEffect(() => {
console.log(value);
}, [value]);
return <></>;
};
const EffEctDemo: React.FC = () => {
const [value, setValue] = useState<number>(0);
return (
<>
<ChildComponent value={value} />
<Button onClick={(e) => setValue(value + 1)}></Button>
</>
);
};
2. 总结
函数式声明组件的方法允许开发者将组件的定义和状态管理分离,使用useState管理状态,配合useEffect使用实现了大部分的生命周期函数的管理,使得代码更加易于理解。