React|React 原理详解
目录
- 1.setState() 说明
- 1.1 更新数据
- 1.2 推荐语法
- 1.3 第二个参数
- 2.JSX 语法的转化过程
- 3.组件更新机制
- 4.组件性能优化
- 4.1 减轻 state
- 4.2 避免不必要的重新渲染
- 总结
1.setState() 说明
1.1 更新数据
setState() 是异步更新数据
可以多次调用 setState() ,只会触发一次重新渲染
import React from 'react'import ReactDOM from 'react-dom'class Opp extends React.Component { state = {count: 1, } handleClick = () => {// 异步更新数据this.setState({count: this.state.count + 1,})this.setState({count: this.state.count + 1,})console.log(this.state.count) // 1 } render() {return (计数器:{this.state.count}) }}ReactDOM.render(, document.getElementById('root'))
1.2 推荐语法
使用 setState((state,props)=>{}) 语法
state:表示最新的 state, props:表示最新的 props
import React from 'react'import ReactDOM from 'react-dom'class Opp extends React.Component { state = {count: 1, } handleClick = () => {/* // 异步更新数据this.setState({count: this.state.count + 1,})console.log(this.state.count) //1this.setState({count: this.state.count + 1,})console.log(this.state.count) //1*/// 推荐语法this.setState((state, props) => {return {count: state.count + 1,}})this.setState((state, props) => {console.log('第二次调用:', state) //2return {count: state.count + 1,}})console.log(this.state.count) // 3 } render() {return (计数器:{this.state.count}) }}ReactDOM.render(, document.getElementById('root'))
1.3 第二个参数
- 在状态更新(页面完成重新渲染)后立即执行某个操作
- 语法:setState(updater[,callback])
callback 是指回调函数 可加可不加
import React from 'react'import ReactDOM from 'react-dom'class Opp extends React.Component { state = {count: 1, } handleClick = () => {this.setState((state, props) => {return {count: state.count + 1,}},// 状态更新后并且重新渲染后,立即执行() => {console.log('状态更新完成:', this.state.count) // 2console.log(document.getElementById('title').innerText) // 计数器:2document.title = '更新后的 count 为:' + this.state.count})console.log(this.state.count) //1 } render() {return (计数器:{this.state.count}) }}ReactDOM.render(, document.getElementById('root'))
2.JSX 语法的转化过程
- JSX 仅仅是 createElement() 方法的语法糖(简化语法)
- JSX 语法被 @babel/preset-react 插件编译为 createElement() 方法
- React元素:是一个对象,用来描述你希望在屏幕上看到的内容
文章图片
import React from 'react'import ReactDOM from 'react-dom'// JSX 语法的转化过程// const element = Hello JSXconst element = React.createElement( 'h1', {className: 'greeting', }, 'Hello JSX')console.log(element)ReactDOM.render(element, document.getElementById('root'))
3.组件更新机制
- setState() 的两个作用:1.修改 state 2.更新组件(UI)
- 过程:父组件重新渲染是,也会重新渲染子组件,但只会渲染当前组件子树(当前组件及其所有子组件)
文章图片
4.组件性能优化
4.1 减轻 state
- 减轻 state :只存储跟组件渲染相关的数据(比如:count /列表数据/ loading 等)
- 注意:不用渲染的书籍不要放在 state 中(比如定时器 id 等)
- 需要在多个方法中用到的数据,应该放在 this 中
4.2 避免不必要的重新渲染
- 组件更新机制:父组件更新会引起子组件也被更新
- 问题:子组件没有变化时也会被重新渲染,造成不必要的重新渲染
- 解决方式:使用钩子函数shouldComponentUpdate(nextProps,nextState)
- 作用:通过返回值决定该组件是否重新渲染,返回 true 表示重新渲染, false 表示不重新渲染
- 触发时机:更新阶段的钩子函数,组件重新渲染前执行(shouldComponentUpdate -> render)
import React from 'react'import ReactDOM from 'react-dom'class Opp extends React.Component { state = {count: 0, } handleClick = () => {this.setState((state) => {return {count: this.state.count + 1,}}) } // 钩子函数 shouldComponentUpdate(nextProps, nextState) {// 返回 false,阻止组件重新渲染// return false// 最新的状态console.log('最新的state', nextState)// 更新前的状态console.log(this.state)// 返回 true,组件重新渲染return true } render() {console.log('组件更新了')return (计数器:{this.state.count}) }}ReactDOM.render(, document.getElementById('root'))
【React|React 原理详解】案例:随机数
通过 nextState
import React from 'react'import ReactDOM from 'react-dom'// 生成随机数class Opp extends React.Component { state = {number: 0, } handleClick = () => {this.setState((state) => {return {number: Math.floor(Math.random() * 3),}}) } // 两次生成的随机数可能相同,则没必要重新渲染 shouldComponentUpdate(nextState) {console.log('最新状态:', nextState, '当前状态:', this.state)return nextState.number !== this.state.number/* if ( nextState.number !== this.state.number) {return true}return false*/ } render() {console.log('render')return (随机数:{this.state.number}) }}ReactDOM.render(, document.getElementById('root'))
通过 nextState
import React from 'react'import ReactDOM from 'react-dom'// 生成随机数class Opp extends React.Component { state = {number: 0, } handleClick = () => {this.setState((state) => {return {number: Math.floor(Math.random() * 3),}}) } render() {return () }}class NumberBox extends React.Component { shouldComponentUpdate(nextProps) {console.log('最新props:', nextProps, '当前props:', this.props)return nextProps.number !== this.props.number } render() {console.log('子组件render')return 随机数:{this.props.number} }}ReactDOM.render( , document.getElementById('root'))
总结 本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!
推荐阅读
- 做一件事情的基本原理是什么()
- Java|Java OpenCV图像处理之SIFT角点检测详解
- C语言浮点函数中的modf和fmod详解
- 【读书笔记】贝叶斯原理
- SG平滑轨迹算法的原理和实现
- “写作宝典”《金字塔原理》之读书笔记
- react|react 安装
- 虚拟DOM-Diff算法详解
- LSTM网络层详解及其应用实例
- OC:|OC: WKWebView详解