React拓展 - setState

setState更新状态的两种写法

1、setState({}, [callback])

export default class Test extends Component {state = {count: 0}add = () => {const { count } = this.statethis.setState({ count: 8 })console.log(this.state.count) // 0 因为setState是异步的,所以会先执行这个// 如果想要在setState操作后,拿state里的值进行操作,需要使用第二个回调函数或async await实现this.setState({ count: 8 }, () => {console.log(this.state.count) // 8})}
}

2、setState(updater, [callback])

export default class Test extends Component {state = {count: 0}add = () => {// 通过函数式,可以获取到state和propsthis.setState((state, props) => {console.log(state, props)return { count: state.count + 1 }}, () => {console.log(this.state.count) // 1})}
}

React拓展 - lazyLoad

路由懒加载

import {Component, lazy, Suspense} from "react"
// 懒加载路由模块
const Home = lazy(() => import("./Home/index"))
const About = lazy(() => import("./About/index"))
export default class Test extends Component {render() {return (<div>{/* Suspense 用于网络不好的时候,显示一个loading加载 */}<Suspense fallback={<h1>Loading...</h1>}><Route path="/home" component={Home}><Route path="/about" component={About}></Suspense></div>)}
}

React拓展 - State Hook

State Hook 为了让使用者在函数式组件里使用state

import React from 'react';
export default function Test2() {// React.useState() 用于初始化一个值,返回一个数组// 数组第一个值为初始化的值// 第二值为一个函数,用于修改第一个值const [count, setCount] = React.useState(0);const [name, setName] = React.useState('杜恒');// 点击事件的回调const changeCount = () => setCount(count + 1);const changeName = () => setName('帅气的杜恒');return (<div><h2>当前值为:{count}</h2><button onClick={changeCount}>+ 1</button><hr /><h2>当前名为:{name}</h2><button onClick={changeName}>改名</button></div>);
}

React拓展 - Effect Hook

Effect Hook 为了让使用者在函数式组件里使用生命周期钩子

import React from 'react';
export default function Test2() {const [count, setCount] = React.useState(0);// React.useEffect 接收两个参数// 第一个参数为函数,这个函数可以用作2个生命周期//   componentDidMount 或 componentDidUpdate// 第二个参数为数组,这个数组用于监听state里的值//   如果为空数组,则第一个参数当componentDidMount使用(只调用一次)//   如果第二个参数没写或数组有值,则第一个参数当componentDidUpdate使用React.useEffect(() => {let timer = setInterval(() => {setCount(count => count + 1);}, 1000);// 当return函数出去时,这个return出去的函数就可以当componentWillUnmount使用return () => {clearInterval(timer);};}, []);return (<div><h2>当前值为:{count}</h2></div>);
}

React拓展 - Ref Hook

Ref Hook 和类式组件里面的createRef一样

import React from 'react';
export default function Test2() {const inputRef = React.useRef();const show = () => console.log(inputRef);return (<div><input type="text" ref={inputRef} /><button onClick={show}>点击提示</button></div>);
}

React拓展 - Fragment

用于多个标签时包裹使用

import React, {Fragment} from 'react';
export default function Test2() {return (<Fragment><input type="text" /><input type="text" /></Fragment>);
}

上面的写法可以写成下面的,直接使用空标签

import React, {Fragment} from 'react';
export default function Test2() {return (<><input type="text" /><input type="text" /></>);
}

React拓展 - Context

Context 用于祖组件向后台组件通信

import React, { Component } from 'react';// 1. 创建TestContext容器
const TestContext = React.createContext();export default class A extends Component {state = { name: '杜恒' };render() {return (<div style={{ background: 'orange', padding: 10 }}>我是A组件{/* 2. 通过 Provider 将所有的state传入到后代组件里 */}<TestContext.Provider value={this.state}><B /></TestContext.Provider></div>);}
}
class B extends Component {render() {return (<div>我是B组件<C /></div>);}
}// 第一种方式
class C extends Component {/* 3. 申明使用context */static contextType = TestContext;render() {console.log(this.context); // {name: "杜恒"}return <div>我是C组件</div>;}
}// 第二种方式
function C() {return (<div><TestContext.Consumer>{ value => console.log(value) }</TestContext.Consumer></div>)
}

React拓展 - 组件优化

组件有以下2个问题

  1. 组件内执行了setState,即使不改变状态数据,也会触发render更新
  2. 父组件render发生更新,会导致子组件的render也会触发

由于render受shouldComponentUpdate的阀门控制,因此需要在shouldComponentUpdate钩子里进行操作

import { Component } from 'react';
export default class A extends Component {state = { count: 0 };/* 赋值一个空对象,并没有改变state的值,也会触发更新 */add = () => this.setState({});/* 通过控制shouldComponentUpdate的返回值,控制是否触发render */shouldComponentUpdate(nextProps, nextState) {console.log(nextProps, nextState);return !this.state.count === nextState.count;}render() {console.log('render函数被触发了');return <button onClick={this.add}>{this.state.count}</button>;}
}

在state里的值少的时候,可以这样写,但是当数据多的时候就不行了,因此另一种方案是将 Component 替换成 PureComponent。
PureComponent 里已经默认实现了 shouldComponentUpdate 里的逻辑,上面的写法可以改成下面的写法

import { PureComponent } from 'react';
export default class A extends PureComponent {state = { count: 0 };add = () => this.setState({});render() {console.log('render函数被触发了');return <button onClick={this.add}>{this.state.count}</button>;}
}

React拓展 - Render Props

import { PureComponent } from 'react';
export default class A extends PureComponent {render() {return (<div><h3>我是A组件</h3><B render={name => <C name={name} />}></B></div>);}
}
class B extends PureComponent {state = { name: '杜恒' };render() {return (<div><h3>我是B组件</h3>{/* 类似插槽的功能 */}{this.props.render(this.state.name)}</div>);}
}
class C extends PureComponent {render() {console.log(this.props);return <div>我是C组件</div>;}
}

错误边界

错误边界用于当子组件出错时,控制错误范围在父组件,不会影响到其他的组件。错误边界只能在生产环境使用,开发环境会一闪而过

import { PureComponent } from 'react';
export default class A extends PureComponent {/* 父组件定义一个状态,用于判断是否出错 */state = {hasError: ''};/* 当后代组件生命周期里有错误时,会触发该函数 */static getDerivedStateFromError(error) {return { hasError: error };}/* 这里可以抓捕到错误后,将错误发送给服务器,服务器在通知到钉钉等 */componentDidCatch() {console.log('组件发生错误!')}render() {return (<div><h3>我是A组件</h3>{/* 动态渲染组件 */}{this.state.hasError ? <h2>子组件出错</h2> : <B />}</div>);}
}
class B extends PureComponent {state = { name: '杜恒' };render() {return (<div><h3>我是B组件</h3>{this.state.name.map(() => (<span>666</span>))}</div>);}
}

1

React学习笔记六 React拓展 - SetState相关推荐

  1. React学习笔记一(React入门+JSX+脚手架)

    文章目录 1. React介绍和特点 1.1 React是什么 1.2 React的特点 2. React的开发依赖 2.1 React的三个依赖 2.2 Babel和React的关系 2.3 Rea ...

  2. java setstate,react学习笔记之state以及setState的使用

    在react中通过 state 以及 setState() 来控制组件的状态. state state 是 react 中用来存储组件数据状态的,可以类比成 vue 中的 data. 1.state的 ...

  3. react学习笔记1--基础知识

    什么是react A JAVASCRIPT LIBRARY FOR BUILDING USER INTERFACES[React是一个用于构建用户界面的JavaScript库.] React之所以快, ...

  4. react组件卸载调用的方法_好程序员web前端培训分享React学习笔记(三)

    好程序员web前端培训分享React学习笔记(三),组件的生命周期 React中组件也有生命周期,也就是说也有很多钩子函数供我们使用, 组件的生命周期,我们会分为四个阶段,初始化.运行中.销毁.错误处 ...

  5. React学习笔记(五) 状态提升

    状态提升究竟是什么东西呢?别急,下面让我们一步一步来看看究竟要怎么使用状态提升 假设我们有这样一个需求,提供两个输入框(分别属于两个组件),保证输入框里面的内容同步 好,下面我们先来封装一个输入框组件 ...

  6. react render没更新_web前端教程分享React学习笔记(一)

    web前端教程分享React学习笔记(一),React的起源和发展:React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写 ...

  7. React学习笔记:入门案例

    React学习笔记:入门案例 React 起源于 Facebook 内部项目,因为市场上所有 JavaScript MVC 框架都不令人满意,公司就决定自己写一套,用来架设 Instagram 的网站 ...

  8. React学习笔记 - 组件Props

    React Learn Note 4 React学习笔记(四) 标签(空格分隔): React JavaScript 三.组件&Props 组件可以将UI切分成一些独立的.可复用的部件,这样你 ...

  9. Ethernet/IP 学习笔记六

    Ethernet/IP 学习笔记六 EtherNet/IP defines two primary types of communications: explicit and implicit (Ta ...

最新文章

  1. Android设计模式系列(3)--SDK源码之单例模式
  2. 02- 流行歌曲 最新热门
  3. python接口测试第二期_python2 接口测试一般方法.
  4. 【数据结构与算法】之深入解析“删除有序数组中的重复项”与“移除元素”的求解思路与算法示例
  5. 241. Different Ways to Add Parentheses
  6. 前端处理跨域的几种方式
  7. 网站前端_EasyUI.基础入门.0009.使用EasyUI Layout组件的最佳姿势?
  8. Linux内核启动去掉企鹅,修改linux内核kernel开机logo(小企鹅)
  9. javascript GlobalEventHandlers
  10. VBS操作XML文档,拷贝结点 (转)
  11. Linux:shell变量功能和Bash shell的操作环境
  12. Word:转换PDF
  13. Java 每半年就会更新一次新特性,再不掌握就要落伍了:Java16 的新特性
  14. css怎么随着鼠标移动,利用CSS sprites制作随着鼠标移动的动画背景
  15. 佩伯尔幻像_幻像类型提高了编译时的安全性
  16. BatteryCapacityCtrl电量控制
  17. omniplan的使用
  18. 使用python破解简单的JavaScript加密的网站
  19. 一下子搞懂JDBC,看这篇就够了--以MySQL为例。
  20. Win7自家OFFICE完美抠图 比ps更简单

热门文章

  1. php 5.5 链接redis,PHP实例:PHP5.5安装PHPRedis扩展及连接测试方法
  2. php怎么循环显示图片,thinkphp 循环显示图片问题!!!~~~~
  3. 软件测试工程师,一个即将消失的职位?
  4. 《数据结构》陈越课件重点总结
  5. java伪唤醒,谈谈JDK线程的伪唤醒
  6. r语言 回归分析 分类变量_R语言进阶之广义线性回归
  7. PAT甲级1002 多项式相加
  8. 地大计算机历年分数线,中国地质大学武汉历年分数线 2021中国地质大学武汉录取分数线...
  9. 如何 调系统相机_神仙理光相机,各种静物原片直出也太美了吧!!!
  10. mexcuda输入nvcc中的参数