React中useEffect使用
之前我们已经掌握了useState的使用,在 class 中,我们通过在构造函数中设置 this.state 为 { count: 0 } 来初始化 count state 为 0:
- class Example extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- count: 0
- };
- }
在函数组件中,我们没有 this,所以我们不能分配或读取 this.state。我们直接在组件中调用 useState Hook:
- import React, { useState } from 'react';
- function Example() {
- // 声明一个叫 “count” 的 state 变量
- const [count, setCount] = useState(0);
既然我们知道了 useState 的作用,那么掌握 useEffect 就更容易,函数组件中没有生命周期,那么可以使用 useEffect 来替代。如果你熟悉 React class 的生命周期函数,你可以把 useEffect Hook 看做 componentDidMount,componentDidUpdate 和 componentWillUnmount 这三个函数的组合。
- class Example extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- count: 0
- };
- }
- componentDidMount() {
- document.title = `You clicked ${this.state.count} times`;
- }
- componentDidUpdate() {
- document.title = `You clicked ${this.state.count} times`;
- }
- render() {
- return (
- <div>
- <p>You clicked {this.state.count} times</p>
- <button onClick={() => this.setState({ count: this.state.count + 1 })}>
- Click me
- </button>
- </div>
- );
- }
- }
使用 Hook 的示例
- import React, { useState, useEffect } from 'react';
- function Example() {
- const [count, setCount] = useState(0);
- useEffect(() => {
- document.title = `You clicked ${count} times`;
- });
- return (
- <div>
- <p>You clicked {count} times</p>
- <button onClick={() => setCount(count + 1)}>
- Click me
- </button>
- </div>
- );
- }
默认情况下,它在第一次渲染之后和每次更新之后都会执行。你可能会更容易接受 effect 发生在“渲染之后”这种概念,不用再去考虑“挂载”还是“更新”。React 保证了每次运行 effect 的同时,DOM 都已经更新完毕。
数据获取,设置订阅以及手动更改 React 组件中的 DOM 都属于副作用。有些副作用可能需要清除,所以需要返回一个函数,比如挂载时设置定时器,卸载时取消定时器。
- class Example extends Component {
- constructor (props) {
- super(props);
- this.state = {
- count: 0
- }
- }
- componentDidMount() {
- this.id = setInterval(() => {
- this.setState({count: this.state.count + 1})
- }, 1000);
- }
- componentWillUnmount() {
- clearInterval(this.id)
- }
- render() {
- return <h1>{this.state.count}</h1>;
- }
- }
使用 Hook 的示例
- function Example() {
- const [count, setCount] = useState(0);
- useEffect(() => {
- const id = setInterval(() => {
- setCount(c => c + 1);
- }, 1000);
- return () => clearInterval(id);
- }, []);
- return <h1>{count}</h1>
- }
你可以通知 React 跳过对 effect 的调用,只要传递数组作为 useEffect 的第二个可选参数即可,如果想执行只运行一次的 effect(仅在组件挂载和卸载时执行),可以传递一个空数组([])作为第二个参数。这就告诉 React 你的 effect 不依赖于 props 或 state 中的任何值,所以它永远都不需要重复执行。
通过跳过 Effect 进行性能优化,在某些情况下,每次渲染后都执行清理或者执行 effect 可能会导致性能问题。在 class 组件中,我们可以通过在 componentDidUpdate 中添加对 prevProps 或 prevState 的比较逻辑解决:
- componentDidUpdate(prevProps, prevState) {
- if (prevState.count !== this.state.count) {
- document.title = `You clicked ${this.state.count} times`;
- }
- }
这是很常见的需求,所以它被内置到了 useEffect 的 Hook API 中。如果某些特定值在两次重渲染之间没有发生变化,你可以通知 React 跳过对 effect 的调用,只要传递数组作为 useEffect 的第二个可选参数即可:
- useEffect(() => {
- document.title = `You clicked ${count} times`;
- }, [count]); // 仅在 count 更改时更新
你已经学习了 State Hook 和 Effect Hook,将它们结合起来你可以做很多事情了。它们涵盖了大多数使用 class 的用例。
完
React中useEffect使用的更多相关文章
- React中useEffect的简单使用
学习hooks 在 React 的世界中, 组件有函数组件和类组件 UI 组件我们可以使用函数,用函数组件来展示 UI. 而对于容器组件,函数组件就显得无能为力. 我们依赖于类组件来获取数据,处理数据 ...
- React 中阻止事件冒泡的问题
在正式开始前,先来看看 JS 中事件的触发与事件处理器的执行. JS 中事件的监听与处理 事件捕获与冒泡 DOM 事件会先后经历 捕获 与 冒泡 两个阶段.捕获即事件沿着 DOM 树由上往下传递,到达 ...
- 哪种方式更适合在React中获取数据?
作者:Dmitri Pavlutin 译者:小维FE 原文:dmitripavlutin.com 国外文章,笔者采用意译的方式,以保证文章的可读性. 当执行像数据获取这样的I/O操作时,你必须发起获取 ...
- React的useEffect与useLayoutEffect执行机制剖析
引言 useEffect和useLayoutEffect是React官方推出的两个hooks,都是用来执行副作用的钩子函数,名字类似,功能相近,唯一不同的就是执行的时机有差异,今天这篇文章主要是从这两 ...
- 解读vue-server-renderer源码并在react中的实现
前言 在博客开发的过程中,有这样一个需求想解决,就是在SSR开发环境中,服务端的代码是是直接通过webpack打包成文件(因为里面包含同构的代码,就是服务端与客户端共享前端的组件代码),写到磁盘里 ...
- react中使用截图组件Cropper组件
--最近项目用react,学习react并使用cropper组件裁剪图片. (这里开发组件不够统一有用tsx(TypeScript + xml/html)写的组件,有用jsx(javascript+x ...
- React报错之React Hook useEffect has a missing dependency
正文从这开始~ 总览 当useEffect钩子使用了一个我们没有包含在其依赖数组中的变量或函数时,会产生"React Hook useEffect has a missing depende ...
- React报错之React Hook 'useEffect' is called in function
正文从这开始~ 总览 为了解决错误"React Hook 'useEffect' is called in function that is neither a React function ...
- 理解React中es6方法创建组件的this
首发于:https://mingjiezhang.github.io/(转载请说明此出处). 在JavaScript中,this对象是运行时基于函数的执行环境(也就是上下文)绑定的. 从react中的 ...
随机推荐
- 国内的go get问题的解决 --gopm
一.golang之旅--gopm 1.什么是gopm 在nodejs中我们有npm,可以通过npm来下载安装一些依赖包.在go中也开发了类似的东西,那就是gopm.这玩意儿是七牛开发的.在这里说下,七 ...
- javascript随机数发现的一个parseInt函数的问题
前几天想伪造一些数据,用到了随机数,没有自己写,便在网上找了一下,找到了这篇文章:https://www.cnblogs.com/starof/p/4988516.html .之后测试了一下,发现了一 ...
- shell 脚本里的$(( ))、$( )、``与${ }的区别
shell 脚本里的命令执行 1. 在bash中,$( )与` `(反引号)都是用来作命令替换的. 命令替换与变量替换差不多,都是用来重组命令行的,先完成引号里的命令行,然后将其结果替换出来,再重组 ...
- React每隔0.2s颜色变淡 之settimeOut变成setInterval
案例 每隔0.2s颜色变淡 公共数据是放在state中的哦! 代码如下 import React, { Component } from "react"; import { set ...
- Bandizip解压压缩软件
上次重装系统以后,特别注意安装软件,在这里提一些比较好的 解压软件:Bandizip 这个是一个免费轻量级的软件,压缩解压速度快,没什么广告,推荐大家在官方下载 Bandizip下载网址 点击下载安装 ...
- python文件的使用
文件是一个存储在辅助存储器上的数据序列,可以包含任何数据内容.概念上,文件是数据的集合抽象,类似地,函数是程序的集合和抽象.用文件形式组织和表达数据更有效也更为灵活.文件包括两种类型:文本文件和二进制 ...
- rpm软件包安装与管理
一.软件包分类 1.软件包分类 源码包 二进制包 2.源码包 2.1 源码包什么样 直接由编程语言写成,没经过编译.类似于java的 .calss 文件,c的 .c文件. [root@love2 ~] ...
- Spring注解的使用和组件扫描
非常重要] 组件扫描(Component-Scan) 通过配置组件扫描,可以使得spring自动扫描package,而不必在spring的配置文件中逐一声明各个<bean> 在配置组件扫描 ...
- Java生鲜电商平台-缓存架构实战
Java生鲜电商平台-缓存架构实战 说明:在Java生鲜电商中,缓存起到了非常重要的作用,目前整个项目中才用的是redis做分布式缓存. 缓存集群 缓存集群存在的问题 1.热key 缓存集群中的某个k ...
- 简单学习HTML
最近突然就对静态页面很有兴趣,主要是看到几个比较酷炫的页面效果,也想自己做一下,但是我的前端页面就是菜鸡,还停留在html+css+jquery的简单使用上,而且还忘记得差不多了! 而且我感觉前端比后 ...