React 原理詳解
阿新 • • 發佈:2021-10-12
目錄
- 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,希望能夠給你帶來幫助,也希望您能夠多多關注我們的更多內容!