1. 程式人生 > 程式設計 >React 原理詳解

React 原理詳解

目錄
  • 1.setState() 說明
    • 1.1 更新資料
    • 1.2 推薦語法
    • 1.3 第二個引數
  • 2.X 語法的轉化過程
    • 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) /www.cppcns.com
        / 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-HkCKSOCKDCdom'
        // 生成隨機數
        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,}
        		})
        	}
        	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'))
        

        總結

        本篇文章就到這裡了HkCKSOCKDC,希望能夠給你帶來幫助,也希望您能夠多多關注我們的更多內容!