React 原理详解

 更新时间:2021年10月10日 11:38:46   作者:keinee  
这篇文章主要介绍了深入理解react的原理,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

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 (
			<div>
				<h1>计数器:{this.state.count}</h1>
				<button onClick={this.handleClick}>+1</button>
			</div>
		)
	}
}
ReactDOM.render(<Opp />, 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) //1
    this.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) //2
			return {
				count: state.count + 1,
			}
		})
		console.log(this.state.count) // 3
	}
	render() {
		return (
			<div>
				<h1>计数器:{this.state.count}</h1>
				<button onClick={this.handleClick}>+1</button>
			</div>
		)
	}
}
ReactDOM.render(<Opp />, 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) // 2
				console.log(document.getElementById('title').innerText) // 计数器:2
				document.title = '更新后的 count 为:' + this.state.count
			}
		)
		console.log(this.state.count) //1
	}
	render() {
		return (
			<div>
				<h1 id='title'>计数器:{this.state.count}</h1>
				<button onClick={this.handleClick}>+1</button>
			</div>
		)
	}
}
ReactDOM.render(<Opp />, 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 = <h1 className='greeting'>Hello JSX</h1>
const 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 (
			<div>
				<h1>计数器:{this.state.count}</h1>
				<button onClick={this.handleClick}>+1</button>
			</div>
		)
	}
}
ReactDOM.render(<Opp />, 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),
			}
		})
	}
	// 两次生成的随机数可能相同,则没必要重新渲染
	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 (
			<div>
				<h1>随机数:{this.state.number}</h1>
				<button onClick={this.handleClick}>重新生成</button>
			</div>
		)
	}
}
ReactDOM.render(<Opp />, 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 (
			<div>
				<NumberBox number={this.state.number} />
				<button onClick={this.handleClick}>重新生成</button>
			</div>
		)
	}
}
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 <h1>随机数:{this.props.number}</h1>
	}
}
ReactDOM.render(<Opp />, document.getElementById('root'))

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!

相关文章

  • React中使用react-json-view展示JSON数据的操作方法

    React中使用react-json-view展示JSON数据的操作方法

    react-json-view是一个用于显示和编辑javascript数组和JSON对象的React组件,本文给大家分享React中使用react-json-view展示JSON数据的操作方法,感兴趣的朋友一起看看吧
    2023-12-12
  • 手把手带你用React撸一个日程组件

    手把手带你用React撸一个日程组件

    这篇文章主要给大家介绍了关于利用React撸一个日程组件的相关资料,包括日常组件的实现思路、使用的技术、以及遇到的技术难点,并给提供了详细的实例代码,需要的朋友可以参考下
    2021-07-07
  • React组件三大核心属性State props Refs介绍

    React组件三大核心属性State props Refs介绍

    组件实例的三大核心属性是:State、Props、Refs。类组件中这三大属性都存在。函数式组件中访问不到 this,也就不存在组件实例这种说法,但由于它的特殊性(函数可以接收参数),所以存在Props这种属性
    2023-02-02
  • React从react-router路由上做登陆验证控制的方法

    React从react-router路由上做登陆验证控制的方法

    本篇文章主要介绍了React从react-router路由上做登陆验证控制的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • React.js Gird 布局编写键盘组件

    React.js Gird 布局编写键盘组件

    这篇文章主要介绍了React.js Gird 布局编写键盘组件,Grid 布局则是将容器划分成"行"和"列",产生单元格,然后指定"项目所在"的单元格,可以看作是二维布局
    2022-09-09
  • 使用React实现一个简单的待办事项列表的示例代码

    使用React实现一个简单的待办事项列表的示例代码

    这篇文章我们将详细讲解如何建立一个这样简单的列表,文章通过代码示例介绍的非常详细,对我们的学习或工作有一定的帮助,需要的朋友可以参考下
    2023-08-08
  • React中事件绑定this指向三种方法的实现

    React中事件绑定this指向三种方法的实现

    这篇文章主要介绍了React中事件绑定this指向三种方法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-05-05
  • React项目中使用zustand状态管理的实现

    React项目中使用zustand状态管理的实现

    zustand是一个用于状态管理的小巧而强大的库,本文主要介绍了React项目中使用zustand状态管理的实现,具有一定的参考价值,感兴趣的可以了解一下
    2023-10-10
  • React中使用TS完成父组件调用子组件的操作方法

    React中使用TS完成父组件调用子组件的操作方法

    由于在项目开发过程中,我们往往时需要调用子组件中的方法,这篇文章主要介绍了React中使用TS完成父组件调用子组件,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-07-07
  • react-native 封装视频播放器react-native-video的使用

    react-native 封装视频播放器react-native-video的使用

    本文主要介绍了react-native 封装视频播放器react-native-video的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01

最新评论