React的setState学习及应用

一:作用:

setState() 将对组件 state 的更改排入队列,并通知 React 需要使用更新后的 state 重新渲染此组件及其子组件。这是用于更新用户界面以响应事件处理器和处理服务器数据的主要方式。

二: 特性

1、为了更好的感知性能,React 会延迟调用它,然后通过一次传递更新多个组件。React 并不会保证 state 的变更会立即生效。批量推迟更新:setState() 是异步的,并且在同一周期内会对多个 setState 进行批处理,后调用的 setState() 将覆盖同一周期内先调用 setState 的值。

import React, {Component} from 'react';

export default class Test extends Component {
constructor(props) {
super(props);
this.state = {
a: 0,
b: 0,
}
} componentDidMount() {
} onClick = () => {
this.setState({
a: this.state.a + 1
})
this.setState({
a: this.state.a + 1
})
this.setState({
b: this.state.b + 1
})
} render() {
console.log('重新渲染', `a=${this.state.a}`, `b=${this.state.b}`);
return (
<div onClick={this.onClick}>按钮</div>
)
} }

打印结果为:

2: 在调用 setState() 后立即读取 this.state,请使用 componentDidUpdate 或者 setState 的回调函数(setState(updater, callback)),这两种方式都可以保证在应用更新后触发。

使用updater函数 (updater 函数中接收的 state 和 props 都保证为最新):

onClick = () => {
this.setState((state, props) => {
return {
a: state.a + 1,
b: state.b + 1,
}
}) this.setState((state, props) => {
return {
a: state.a + 1,
b: state.b + 1,
}
})
}

打印结果为:

这里并没有打印两次,说明updater函数也是批量推迟更新。

使用回调函数: setState() 的第二个参数为可选的回调函数,它将在 setState 完成合并并重新渲染组件后执行。通常,我们建议使用 componentDidUpdate() 来代替此方式。

onClick = () => {
this.setState({
a: this.state.a + 1,
b: this.state.b + 1,
}, () => {
this.setState({
a: this.state.a + 1,
b: this.state.b + 1,
})
})
}

打印结果为:

使用componentDidUpdate()。此生命周期和render()一样,都不能在内部使用setstate方法,不然会导致死循环,只能读,不能改。

componentDidUpdate() {
console.log('重新渲染结束', `a=${this.state.a}`, `b=${this.state.b}`);
} onClick = () => {
this.setState({
a: this.state.a + 1,
b: this.state.b + 1,
})
}

打印结果为:

三:setstate是异步还是同步?

有时表现出异步,有时表现出同步

1、setState只在合成事件和钩子函数中是“异步”的,在原生事件和setTimeout 中都是同步的。

2、setState 的“异步”并不是说内部由异步代码实现,其实本身执行的过程和代码都是同步的,只是合成事件和钩子函数的调用顺序在更新之前,导致在合成事件和钩子函数中没法立马拿到更新后的值,形成了所谓的“异步”,当然可以通过第二个参数 setState(partialState, callback) 中的callback拿到更新后的结果。

3、setState 的批量更新优化也是建立在“异步”(合成事件、钩子函数)之上的,在原生事件和setTimeout 中不会批量更新。

settimeout

onClick = () => {
setTimeout(() => {
this.setState({
a: this.state.a + 1,
b: this.state.b + 1,
})
this.setState({
a: this.state.a + 1,
b: this.state.b + 1,
})
})
}

打印结果为:

原生事件:

componentDidMount() {
const btn = document.getElementById('btn');
btn.addEventListener('click', this.onDomClick, false)
} onDomClick = () => {
this.setState({
a: this.state.a + 1,
b: this.state.b + 1,
})
this.setState({
a: this.state.a + 1,
b: this.state.b + 1,
})
} render() {
console.log('重新渲染', `a=${this.state.a}`, `b=${this.state.b}`);
return (
<div id='btn'>按钮</div>
)
}

打印结果为:

React的setState学习及应用的更多相关文章

  1. React中setState学习总结

    react中setState方法到底是异步还是同步,其实这个是分在什么条件下是异步或者同步. 1.先来回顾一下react组件中改变state的几种方式: import React, { Compone ...

  2. React的setState分析

    前端框架层出不穷,不过万变不离其宗,就是从MVC过渡到MVVM.从数据映射到DOM,angular中用的是watcher对象,vue是观察者模式,react就是state了. React通过管理状态实 ...

  3. React中setState同步更新策略

    setState 同步更新 我们在上文中提及,为了提高性能React将setState设置为批次更新,即是异步操作函数,并不能以顺序控制流的方式设置某些事件,我们也不能依赖于this.state来计算 ...

  4. 初学React,setState后获取到的thisstate没变,还是初始state?

    问题:(javascript)初学React,setState后获取到的thisstate没变,还是初始state?描述: getInitialState(){ return {data:[]}; } ...

  5. 「React Native笔记」在React的 setState 中操作数组和对象的多种方法(合集)

    运用在React 中 setState的对象.数组的操作时是不能用类似array.push()等方法,因为push没有返回值,setState后会出现state变成Number,为了方便他人和自己查看 ...

  6. React中setState 什么时候是同步的,什么时候是异步的?

    class Example extends React.Component { constructor() { super(); this.state = { val: 0 }; } componen ...

  7. 最新 React 源码学习笔记

    最新 React 源码学习笔记 v17.x.x 框架架构 核心算法 设计模式 编码风格 项目结构 为什么出现 解决了什么问题 有哪些应用场景 refs https://github.com/learn ...

  8. React.js深入学习详细解析

    今天,继续深入学习react.js. 目录: 一.JSX介绍 二.React组件生命周期详解 三.属性.状态的含义和用法 四.React中事件的用法 五.组件的协同使用 六.React中的双向绑定   ...

  9. React官网学习笔记

    欢迎指导与讨论 : ) 前言 本文主要是笔者在React英文官网学习时整理的笔记.由于笔者水平有限,如有错误恳请指出 O(∩_∩)O 一 .Tutoial 篇 1 . React的组件类名的首字母必须 ...

随机推荐

  1. Thinkphp5——数据库表名的大小写问题

    ThinkPHP5中数据库的表名如果是驼峰命名法,会被转换成小写加下划线,解决方法如下: 1.表名全部小写,因为数据库的表名区分大小写的. 2.使用Db::table("表名"), ...

  2. nginx的部署及配置文件的介绍 域名 用户认证 SSL加密模块

    步骤一:构建Nginx服务器 yum -y install gcc pcre-devel openssl-devel        #安装依赖包 wget   http://nginx.org/dow ...

  3. std::unique_ptr的用法

    std::ofstream("demo.txt") << 'x'; // 准备要读的文件 { std::unique_ptr<std::FILE, decltyp ...

  4. python操作s3服务中的文件

    亚马逊云aws提供了s3服务.国内一些云厂商也用了s3技术.要操作s3服务器中的文件需要用到boto这个python包.下面的代码是一个简单例子. #! /usr/bin/python # -*-co ...

  5. linux终端界面的字颜色设置

    目录 目录 说明 PS1 颜色语法 保存设置 说明 在网上找了好多资料都不是很详细,要不就是语法有错误. 所以弄了好久才整明白了,写下来方便后面的人学习. 本人linux虚拟机版本为CentOs 6. ...

  6. Cookie俩步操作实现n天免登陆

    实现这个功能主要思路是:在登录成功的时候去给用户名和密码加上Cookie,将他们的值存在Cookie中,为了下次登录记住用户名和密码,然后在登录界面,获取所有的cookie,然后将值一一遍历出来.和用 ...

  7. [TimLinux] CSS 实现加载中的动画

    内容来自对<CSS世界>学习代码的理解简化: <!DOCTYPE html> <html> <head> <style> div { pad ...

  8. nginx编译安装配置模块大全

    使用configure命令配置构建.它定义了系统的各个方面,包括允许nginx用于连接处理的方法.最后,它会创建一个Makefile.该configure命令支持以下参数:--help 打印帮助信息. ...

  9. Python3 网络基础基础2

    目录 subprocess 粘包问题 问题原因 解决问题 上传大文件 UDP协议 SocketServer subprocess 可以通过代码执行操作系统的终端命令, 并返回终端执行命令后的结果 im ...

  10. Orleans[NET Core 3.1] 学习笔记(二)Hello World

    项目结构 开始Orleans之前,我们都知道Orleans主要可以分为俩部分,Host和Client. 所以我们可以创建如下的项目结构: IGrain 一个包含Grain接口的库(.NET Stand ...