React 原理详解

2022-04-15 0 282
目录
  • 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 (
        			<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元素:是一个对象,用来描述你希望在屏幕上看到的内容

        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)
        • 过程:父组件重新渲染是,也会重新渲染子组件,但只会渲染当前组件子树(当前组件及其所有子组件)

        React 原理详解

        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'))
        

        总结

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

        免责声明:
        1、本网站所有发布的源码、软件和资料均为收集各大资源网站整理而来;仅限用于学习和研究目的,您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。 不得使用于非法商业用途,不得违反国家法律。否则后果自负!

        2、本站信息来自网络,版权争议与本站无关。一切关于该资源商业行为与www.niceym.com无关。
        如果您喜欢该程序,请支持正版源码、软件,购买注册,得到更好的正版服务。
        如有侵犯你版权的,请邮件与我们联系处理(邮箱:skknet@qq.com),本站将立即改正。

        NICE源码网 JavaScript React 原理详解 https://www.niceym.com/25739.html