React学习笔记六 React拓展 - SetState
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个问题
- 组件内执行了setState,即使不改变状态数据,也会触发render更新
- 父组件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相关推荐
- React学习笔记一(React入门+JSX+脚手架)
文章目录 1. React介绍和特点 1.1 React是什么 1.2 React的特点 2. React的开发依赖 2.1 React的三个依赖 2.2 Babel和React的关系 2.3 Rea ...
- java setstate,react学习笔记之state以及setState的使用
在react中通过 state 以及 setState() 来控制组件的状态. state state 是 react 中用来存储组件数据状态的,可以类比成 vue 中的 data. 1.state的 ...
- react学习笔记1--基础知识
什么是react A JAVASCRIPT LIBRARY FOR BUILDING USER INTERFACES[React是一个用于构建用户界面的JavaScript库.] React之所以快, ...
- react组件卸载调用的方法_好程序员web前端培训分享React学习笔记(三)
好程序员web前端培训分享React学习笔记(三),组件的生命周期 React中组件也有生命周期,也就是说也有很多钩子函数供我们使用, 组件的生命周期,我们会分为四个阶段,初始化.运行中.销毁.错误处 ...
- React学习笔记(五) 状态提升
状态提升究竟是什么东西呢?别急,下面让我们一步一步来看看究竟要怎么使用状态提升 假设我们有这样一个需求,提供两个输入框(分别属于两个组件),保证输入框里面的内容同步 好,下面我们先来封装一个输入框组件 ...
- react render没更新_web前端教程分享React学习笔记(一)
web前端教程分享React学习笔记(一),React的起源和发展:React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写 ...
- React学习笔记:入门案例
React学习笔记:入门案例 React 起源于 Facebook 内部项目,因为市场上所有 JavaScript MVC 框架都不令人满意,公司就决定自己写一套,用来架设 Instagram 的网站 ...
- React学习笔记 - 组件Props
React Learn Note 4 React学习笔记(四) 标签(空格分隔): React JavaScript 三.组件&Props 组件可以将UI切分成一些独立的.可复用的部件,这样你 ...
- Ethernet/IP 学习笔记六
Ethernet/IP 学习笔记六 EtherNet/IP defines two primary types of communications: explicit and implicit (Ta ...
最新文章
- Android设计模式系列(3)--SDK源码之单例模式
- 02- 流行歌曲 最新热门
- python接口测试第二期_python2 接口测试一般方法.
- 【数据结构与算法】之深入解析“删除有序数组中的重复项”与“移除元素”的求解思路与算法示例
- 241. Different Ways to Add Parentheses
- 前端处理跨域的几种方式
- 网站前端_EasyUI.基础入门.0009.使用EasyUI Layout组件的最佳姿势?
- Linux内核启动去掉企鹅,修改linux内核kernel开机logo(小企鹅)
- javascript GlobalEventHandlers
- VBS操作XML文档,拷贝结点 (转)
- Linux:shell变量功能和Bash shell的操作环境
- Word:转换PDF
- Java 每半年就会更新一次新特性,再不掌握就要落伍了:Java16 的新特性
- css怎么随着鼠标移动,利用CSS sprites制作随着鼠标移动的动画背景
- 佩伯尔幻像_幻像类型提高了编译时的安全性
- BatteryCapacityCtrl电量控制
- omniplan的使用
- 使用python破解简单的JavaScript加密的网站
- 一下子搞懂JDBC,看这篇就够了--以MySQL为例。
- Win7自家OFFICE完美抠图 比ps更简单
热门文章
- php 5.5 链接redis,PHP实例:PHP5.5安装PHPRedis扩展及连接测试方法
- php怎么循环显示图片,thinkphp 循环显示图片问题!!!~~~~
- 软件测试工程师,一个即将消失的职位?
- 《数据结构》陈越课件重点总结
- java伪唤醒,谈谈JDK线程的伪唤醒
- r语言 回归分析 分类变量_R语言进阶之广义线性回归
- PAT甲级1002 多项式相加
- 地大计算机历年分数线,中国地质大学武汉历年分数线 2021中国地质大学武汉录取分数线...
- 如何 调系统相机_神仙理光相机,各种静物原片直出也太美了吧!!!
- mexcuda输入nvcc中的参数