React-hooks:useEffect

8 篇文章 0 订阅
useEffect 永远是在 DOM渲染完成之后执行
1.理解函数副作用
什么是副作用?

对于React组件来说,主作用是根据数据(state/props)渲染UI,除此之外都是副作用(比如手动修改DOM、发送ajax请求)。

常见的副作用
  1. 数据请求(发送ajax)
  2. 手动修改 DOM
  3. localstorage操作

useEffect 函数的作用就是为react函数组件提供副作用

2.基础使用
使用步骤
  1. 导入 useEffect 函数
  2. 调用 useEffect 函数,并传入回调函数
  3. 在回调函数中编写副作用处理
  4. 修改数据状态
  5. 检测副作用是否生效
示例代码
import {useState, useEffect} from 'react';

function App() {
	const [count, setCount] = useState(0);

	useEffect(() => {
		console.log("触发副作用");
		document.title = `点击了${count}`;
	});

	return (
		<div>
			<button onClick={() => setCount(count + 1)}>点击{count}</button>
		</div>
	)
}
3.依赖项控制 副作用执行时机
1.默认状态(无依赖项)

上边的示例中,组件初始化时先触发一次(console出内容),之后每次点击按钮,都会触发 副作用。
useEffect 可执行多次

2.依赖项 为空

useEffect 函数还可以接收第二个参数,作为该副作用的依赖项,当第二个参数 传入一个空数组[] 时,表明只有 组件初始化的时候执行一次
咱们对上边的案例做下 微调

function App() {
	const [count, setCount] = useState(0);

	useEffect(() => {
		console.log("触发副作用");
		document.title = `点击了${count}`;
	}, []); // 注意这里,传入 []

	return (
		<div>
			<button onClick={() => setCount(count + 1)}>点击{count}</button>
		</div>
	)
}

可以看到当点击按钮时,title 不再改变。

3.依赖特定项

当依赖项数组中传入值时,那么该副作用会在 组件初始化的时候执行一次,依赖的特定项变化时会再次执行

function App() {
  const [count, setCount] = useState(0);
  const [name, setName] = useState('李白');

  useEffect(() => {
    console.log('触发渲染')
    document.title = `clicked ${count} times`;
    console.log('name: ', {name});
  },[count]) // 这里我们传入 count,不传name

  return (
    <>
      <p>当前次数:{count}</p>
      <p><button onClick={() => setCount(count + 1)}>累计</button></p>
      <p><button onClick={() => setName("杜甫")}>改名{name}</button></p>
    </>
  )
}

如上,当我们点击 “累计” 按钮时,会console内容,title也会改变,但是我们点击 “改名”时,不会发生变化,就是因为我们在依赖项数组中传入了 “count” 而没有 “name”。

依赖项和执行时机如下所示:
在这里插入图片描述

4.注意事项

只要在 useEffect 回调函数中用到的数据状态就应该出现在依赖项数组中声明,否则可能会有bug。

5.清除副作用

在组件被销毁时,如果有些副作用操作需要被清理,比如常见的定时器等,可通过useEffect return回调函数 的方式清理副作用。

语法如下:

useEffect(() => {
	console.log('副作用函数执行');
	return () => {
		console.log('清理副作用的函数执行');
		// 这里执行 清理副作用的代码
	}
})

示例:

function Test() {
  useEffect(() => {
    let timer = setInterval(() => {
      console.log('this is effect');
    }, 1000)

    // 这里return 一个回调函数,在函数中清除副作用
    return () => {
      clearInterval(timer);
    }
  })

  return (
    <div>Test</div>
  )
}

function App() {
  const [flag, setFlag] = useState(true);

  return (
    <div>
      {flag ? <Test/> : null}
      <div>
        <button onClick={() => setFlag(!flag)}>点击</button>
      </div>
    </div>
  )
}
6.发送网络请求

不可以直接在 useEffect 的回调函数外层直接包裹await,因为异步会导致清理函数无法立即返回
❌错误示例:

useEffect(async () => {
	const res = await getData('url');
	console.log(res);
})

可在 useEffect 中定义一个请求数据方法,调用。

正确示例

useEffect(() => {
	async function initData() {
		const res = await getData('url');
		console.log(res);
	}
	
	initData()
}, []) // 仅组件初始化时调用
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端卡卡西呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值