hook 面试题

本文详细探讨了React中的useEffectHook,包括如何模拟componentDidMount,正确处理数据请求,依赖数组的作用,以及函数作为依赖的使用。强调了函数组件与class组件的区别,并提供了useEffect的最佳实践,如如何避免无限请求和确保获取最新状态。
摘要由CSDN通过智能技术生成

useEffect

在 React 中,useEffect 是一个用于处理副作用的 Hook。useEffect 接受两个参数:第一个参数是一个函数,用于执行副作用逻辑,第二个参数是一个数组,用于指定依赖项。

当依赖项数组为空(即不传递)时,useEffect 中的副作用逻辑只会在组件首次渲染时执行,而不会在之后的渲染中再次执行。

1. 🤔 如何用useEffect模拟componentDidMount生命周期?

对于这个问题,大家会习惯性的想到useEffect(()=>{fetchData()}),[]),将依赖项数组置为空即可,这是一个管用的方法,可是这个问题是个陷阱。函数组件和class组件的心智模型是不一样的,不能把他们混为一谈,在我看来,他们最大的区别是当状态变化时,函数组件相当于经历了轮回,从种子长成花朵,再从花朵结成种子,不同年份的花朵看起来一样,但终究不是同一朵,而class组件相当于一朵花,从鲜艳的花朵变成干花束,形态不同,但始终是那一朵。

2. 🤔 如何正确地在useEffect里请求数据?[]又是什么?

每个useEffect都是不同的,随着状态的变化,一个个effect出生,一个个effect死去,怎么保证出生的effect是我们想要的呢,这就需要借助依赖数组来注入遗传因子,请求过程中用到的所有的遗传因子都要写到数组里,当然这是最保险的方法,如果想更优雅一些,可以看引用文献及下面的实践总结

3. 🤔 我应该把函数当做effect的依赖吗?

可以把函数作为effect的依赖。更多关于函数的最佳实践看下面的实践总结。

4. 🤔 为什么有时候会出现无限重复请求的问题?

分为两种情况,一种是没有依赖数组,那么每次渲染都会触发这个副作用,例如

useEffect(()=>{
    fetchData()
})

还有一种是设置了依赖数组,但是依赖数组里的变量一直在变,例如

scss
复制代码const [data,setData] = useState()

useEffect(()=>{
    const fetchData = async() => {
        const res = await fetchNewData()
        setData(res.data)
    }
    fetchData()
},[data])

5. 🤔 为什么有时候在effect里拿到的是旧的state或prop?

effect里获取的始终应该是最新的state或prop,如果出现旧的state或prop,一定是因为依赖数组中的依赖项不完整,没能触发effect更新。

useEffect最佳实践总结

1.class组件和函数组件的区别

  • 每一个函数、每一个useEffect中的props和state都是独立的。不是state在不变的effect中变化,而是每一个effect中有不变的state
  • 函数组件的状态会停留在某个状态,改变后的状态跟前者不是同一个,所以不同时机不同状态;class组件中,状态始终指向this.state,不同时机但是同一个状态
  • useEffect并不等于componentDidmount + componentDieUpdate,将函数传入到子组件,如何仅在需要的时候触发这个请求,是分辨两者的最佳办法,函数式组件传入的函数是类的一个属性,是永远不会变的,他永远只会请求一次数据,如果传入它的依赖参数,依赖参数默认是一直变动的,所以就会一直重新请求数据。如果用hooks传递,设置好适当的依赖项,就只会在依赖项变动的时候重新请求数据
  • useEffect先渲染,后执行preState和curState的副作用

2. 如何定义函数和请求

  • 某些函数只在effect中使用的话,那就在effect里定义
  • 某些函数在多个地方用到,就独立定义,最好用useCallBack包裹,并且在依赖数组里把依赖项写全
  • useEffect回调函数不能用async修饰,但是可以在回调函数内部重新写一个async函数,然后调用
scss
复制代码 //不可以
useEffect(async()=>{
    const res = await fetchNewData(id)
    setData(res.data)
},[id])


//推荐
useEffect(()=>{
    const fetchData = async() => {
        const res = await fetchNewData(id)
        setData(res.data)
    }
    fetchData()
},[id])

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值