欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript中React 面向組件編程(下)

 更新時間:2023年03月30日 11:56:12   作者:清風 與我  
在React面向組件編程中,除了上一章節(jié)的組件實例的三大核心屬性以外,還有很多重要的內(nèi)容比如:React 的生命周期,受控組件與非受控組件,高階函數(shù)和函數(shù)柯里化的理解等,在本文中會給大家繼續(xù)講解React 面向組件編程中剩余的內(nèi)容

前言:

在React面向組件編程中,除了上一章節(jié)的組件實例的三大核心屬性以外,還有很多重要的內(nèi)容比如:React 的生命周期,受控組件與非受控組件,高階函數(shù)和函數(shù)柯里化的理解等,在本文中會給大家繼續(xù)講解React 面向組件編程中剩余的內(nèi)容。

一、受控組件與非受控組件

表單的組件分類:

  1. 受控組件
  2. 非受控組件

多數(shù)情況下,推薦使用受控組件實現(xiàn)表單。在受控組件中,表單數(shù)據(jù)由組件控制。
另外一種是非受控組件,這種方式下表單組件由DOM自身控制。

 1. 受控組件

  1. 受控組件通過 props 獲取其當前值,并通過回調(diào)函數(shù)(比如 onChange )通知變化
  2. 表單狀態(tài)發(fā)生變化時,都會通知 React,將狀態(tài)交給 React 進行處理,比如可以使用 useState 存儲
  3. 受控組件中,組件渲染出的狀態(tài)與它的 value 或 checked 屬性相對應
  4. 受控組件會更新 state 的流程
class Login extends React.Component {
    // 初始化狀態(tài)
    state = {
        username:'', // 用戶名
        password:'', // 密碼
    }
    // 保存用戶名到狀態(tài)中
    saveUsername=(event)=>{
        this.setState({username:event.target.value})
    }
    // 保存密碼到狀態(tài)中
    savePassword=(event)=>{
        this.setState({password:event.target.value})
    }
    // 表單提交的回調(diào)
    handleSubmit=(event)=>{
        event.preventDefault(); // 阻止默認事件
        
        let {username,password} = this.state
        alert(`你輸入的用戶名是${username},密碼是${password}`)
    }
    render(){
        return(
            <div>
                <form action="https://www.baidu.com/" onSubmit={this.handleSubmit}>
                    用戶名:<input type="text" onChange={this.saveUsername} name="username" />    
                    密碼:<input type="text" onChange={this.savePassword} name="password" />
                    <button type="submit">登錄</button>  
                </form>
            </div>
        )
    }
}

2. 非受控組件

非受控組件將數(shù)據(jù)存儲在 DOM 中,而不是組件內(nèi),這比較類似于傳統(tǒng)的 HTML 表單元素。

  1. 非受控組件的值不受組件自身的 state 和 props 控制
  2. 非受控組件使用 ref 從 DOM 中獲取元素數(shù)據(jù)
class Login extends React.Component {
    handleSubmit=(event)=>{
        // console.log(e>=event)
        event.preventDefault(); // 阻止默認事件
        
        let {username,password} = this
        alert(`你輸入的用戶名是${username.value},密碼是${password.value}`)
    }
    render(){
        return(
            <div>
                <form action="https://www.baidu.com/" onSubmit={this.handleSubmit}>
                    用戶名:<input type="text" ref={c=>this.username = c} name="username" />    
                    密碼:<input type="text" ref={c=>this.password = c} name="password" />
                    <button type="submit">登錄</button>  
                </form>
            </div>
        )
    }
}

 3. 效果展示

4. 總結(jié):

  1. React 中的組件分為受控組件和非受控組件
  2. 受控組件的兩個要點:
    • 組件的 value 屬性與 React 中的狀態(tài)綁定
    • 組件內(nèi)聲明了 onChange 事件處理 value 的變化
  3. 非受控組件更像是傳統(tǒng)的 HTML 表單元素,數(shù)據(jù)存儲在 DOM 中,而不是組件內(nèi)部,獲取數(shù)據(jù)的方式是通過 ref 引用
  4. 一些建議:
    • 盡可能使用受控組件
    • 受控組件是將狀態(tài)交由 React 處理,可以是任何元素,不局限于表單元素
    • 對于有大量表單元素的頁面,使用受控組件會使程序變得繁瑣難控,此時使用非受控組件更為明智
    • 在受控組件中,數(shù)據(jù)流是單向的( state 是變化來源),因此在改變 state 時都應該使用 setState ,而不要強制賦值
    • Refs 不能用于函數(shù)式組件,因為函數(shù)式組件沒有實例
    • 在函數(shù)式組件內(nèi)部,是可以使用 Refs 的

 二、組件的生命周期

所謂的React生命周期,就是指組件從被創(chuàng)建出來,到被使用,最后被銷毀的這么一個過程;
而在這個過程中,React提供了我們會自動執(zhí)行的不同的鉤子函數(shù),我們稱之為生命周期函數(shù);

組件的生命周期大致分為三個階段:組件掛載階段,組件更新階段,組件銷毀卸載階段

react在版本16.3前后存在兩套生命周期,16.3之前為舊版,之后則是新版,雖有新舊之分,但主體上大同小異。

 1. 對生命周期的理解

  1. 組件從創(chuàng)建到死亡它會經(jīng)歷一些特定的階段。
  2. React組件中包含一系列勾子函數(shù)(生命周期回調(diào)函數(shù)), 會在特定的時刻調(diào)用。
  3. 我們在定義組件時,會在特定的生命周期回調(diào)函數(shù)中,做特定的工作。

 2. 生命周期的三個階段(舊)

  1. 初始化階段: 由ReactDOM.render()觸發(fā)—初次渲染
    1. constructor()
    2. componentWillMount()
    3. render()
    4. componentDidMount()
  2. 更新階段: 由組件內(nèi)部this.setSate()或父組件重新render觸發(fā)
    1. shouldComponentUpdate()
    2. componentWillUpdate()
    3. render()
    4. componentDidUpdate()
  3. 卸載組件: 由ReactDOM.unmountComponentAtNode()觸發(fā)
    1. componentWillUnmount()
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>生命周期舊</title>
</head>
<body>
    <!-- 準備好一個容器 -->
    <div id="test"></div>
    <!-- 引入 React 核心庫 -->
    <script src="../js/react.development.js"></script>
    <!-- 引入 react-dom 用于支持 react 操作 DOM -->
    <script src="../js/react-dom.development.js"></script>

    <!-- 引入babel:
            1. ES6 ==> ES5
            2. jsx ==> js
    -->
    <script src="../js/babel.min.js"></script>

    <script type="text/babel">
        class Count extends React.Component {
            state = {
                count:0
            }
            add = ()=>{
                // 獲取原狀態(tài)
                let {count} = this.state
                // 更新狀態(tài)
                this.setState({count:count+1})
            }
            death = ()=>{
                ReactDOM.unmountComponentAtNode(document.getElementById('test'))
            }
            force = ()=>{
                this.forceUpdate() // 強制更新
            }
            // 數(shù)據(jù)更新的 ‘閥門~'
            shouldComponentUpdate() { 
                console.log("Count --- shouldComponentUpdate");
                return true // 這里必須有返回4值,其次返回值默認是true
            }
            // 組件將要更新的鉤子
            componentWillUpdate() {
                console.log("Count ---- componentWillUpdate");
            }
            // 組件更新完成的鉤子
            componentDidUpdate() { 
                console.log("Count ---- componentDidUpdate");
            } 
            render(){
                console.log("render");
                let {count} = this.state
                return(
                    <div>
                        <h2>當前求和為:{count}</h2>
                        <button onClick={this.add}>點我+1</button>
                        <button onClick={this.death}>卸載組件</button>
                        <button onClick={this.force}>不更改任何狀態(tài)中的數(shù)據(jù),強制更新</button>
                    </div>
                )
            }
        }

        // 父組件
        class A extends React.Component {
            state = {carName:'小三輪'}
            changeCar = ()=>{
                this.setState({carName:"賓利"})
            }
            render(){
                console.log('A ---- render');
                return(
                    <div>
                        <div>我是A組件</div>
                        <button onClick={this.changeCar}>換車</button>
                        <B carName={this.state.carName}></B>
                    </div>
                )
            }
        }
        // 子組件
        class B extends A {
            // 組件將要接收新的props的鉤子
            componentWillReceiveProps(){
                console.log('B ---- componentWillReceiveProps');
            }
            // 數(shù)據(jù)更新的 ‘閥門~'
            shouldComponentUpdate() { 
                console.log("B --- shouldComponentUpdate");
                return true // 這里必須有返回4值,其次返回值默認是true
            }
            // 組件將要更新的鉤子
            componentWillUpdate() {
                console.log("B ---- componentWillUpdate");
            }
            // 組件更新完成的鉤子
            componentDidUpdate() { 
                console.log("B ---- componentDidUpdate");
            } 
            render(){
                console.log('B ---- render');
                return(
                    <div>
                        我是B組件,接收到的車是:{this.props.carName}
                    </div>
                )
            }
        }

        ReactDOM.render(<A />,document.getElementById('test'))
    </script>
</body>
</html>

3. 生命周期的三個階段(新)

  1. 初始化階段: 由ReactDOM.render()觸發(fā)—初次渲染
    1. constructor()
    2. getDerivedStateFromProps
    3. render()
    4. componentDidMount()
  2. 更新階段: 由組件內(nèi)部this.setSate()或父組件重新render觸發(fā)
    1. getDerivedStateFromProps
    2. shouldComponentUpdate()
    3. render()
    4. getSnapshotBeforeUpdate
    5. componentDidUpdate()
  3. 卸載組件: 由ReactDOM.unmountComponentAtNode()觸發(fā)
    1. componentWillUnmount()
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>生命周期新</title>
</head>
<body>
    <!-- 準備好一個容器 -->
    <div id="test"></div>
    <!-- 引入 React 核心庫 -->
    <script src="../js/17.0.1/react.development.js"></script>
    <!-- 引入 react-dom 用于支持 react 操作 DOM -->
    <script src="../js/17.0.1/react-dom.development.js"></script>
    <!-- 引入babel:1. ES6 ==> ES52. jsx ==> js -->
    <script src="../js/17.0.1/babel.min.js"></script>
    <script type="text/babel">
        class Count extends React.Component {
            state = {
                count:0
            }
            add = ()=>{
                // 獲取原狀態(tài)
                let {count} = this.state
                // 更新狀態(tài)
                this.setState({count:count+1})
            }
            death = ()=>{
                ReactDOM.unmountComponentAtNode(document.getElementById('test'))
            }
            force = ()=>{
                this.forceUpdate() // 強制更新
            }
            // 數(shù)據(jù)更新的 ‘閥門~'
            shouldComponentUpdate() { 
                console.log("Count --- shouldComponentUpdate");
                return true // 這里必須有返回4值,其次返回值默認是true
            }
            // 組件將要更新的鉤子
            componentWillUpdate() {
                console.log("Count ---- componentWillUpdate");
            }
            // 組件更新完成的鉤子
            componentDidUpdate() { 
                console.log("Count ---- componentDidUpdate");
            } 
            render(){
                console.log("render");
                let {count} = this.state
                return(
                    <div>
                        <h2>當前求和為:{count}</h2>
                        <button onClick={this.add}>點我+1</button>
                        <button onClick={this.death}>卸載組件</button>
                        <button onClick={this.force}>不更改任何狀態(tài)中的數(shù)據(jù),強制更新</button>
                    </div>
                )
            }
        }

        // 父組件
        class A extends React.Component {
            state = {carName:'小三輪'}
            
            constructor(props) {
                state
            }
            changeCar = ()=>{
                this.setState({carName:"賓利"})
            }
            static getDerivedStateFromProps(props, state) {
                // 這里必須要一個返回值 ==> state or null
                // 這里的state會覆蓋掉原本的狀態(tài),并且后續(xù)也無法修改
                // 能將外部的接收的props 賦值給組件自身的 state
                // 如果你希望自身的state一直,全部依賴于外部的props,那么可以使用這個生命周期函數(shù)
                return {carName:"QQ"}
            }
            // 獲取護具更新前的快照,能拿到舊的props和state
            // 必須有返回值
            getSnapshotBeforeUpdate = (prevProps, prevState) => {

            }
            render(){
                console.log('A ---- render');
                return(
                    <div>
                        <div>我是A組件</div>
                        <button onClick={this.changeCar}>換車</button>
                        <B carName={this.state.carName}></B>
                    </div>
                )
            }
        }
        // 子組件
        class B extends A {
            // 組件將要接收新的props的鉤子
            UNSAFE_componentWillReceiveProps(){
                console.log('B ---- componentWillReceiveProps');
            }
            // 數(shù)據(jù)更新的 ‘閥門~'
            shouldComponentUpdate() { 
                console.log("B --- shouldComponentUpdate");
                return true // 這里必須有返回4值,其次返回值默認是true
            }
            // 將要掛載時
            UNSAFE_componentWillMount() {
                console.log("Count --- componentWillUnMount");
            }
            // 組件將要更新的鉤子
            UNSAFE_componentWillUpdate() {
                console.log("B ---- componentWillUpdate");
            }
            // 組件更新完成的鉤子
            componentDidUpdate() { 
                console.log("B ---- componentDidUpdate");
            } 
            render(){
                console.log('B ---- render');
                return(
                    <div>
                        我是B組件,接收到的車是:{this.props.carName}
                    </div>
                )
            }
        }

        ReactDOM.render(<A />,document.getElementById('test'))
    </script>
</body>
</html>

4. 新舊生命周期的區(qū)別

  1. 新生命周期中去掉了三個 will 鉤子,分別為 componentWillMountcomponentWillReceiveProps、componentWillUpdate;
  2. 新生命周期中新增了兩個鉤子,分別為 getDerivedStateFromProps(從 props 中得到衍生的 state )和 getSnapshotBeforeUpdate。

5. 重要的勾子

  1. render:初始化渲染或更新渲染調(diào)用
  2. componentDidMount:開啟監(jiān)聽, 發(fā)送ajax請求
  3. componentWillUnmount:做一些收尾工作, 如: 清理定時器

6. 即將廢棄的勾子

  1. componentWillMount
  2. componentWillReceiveProps
  3. componentWillUpdate

警告:

現(xiàn)在使用會出現(xiàn)警告,下一個大版本需要加上 UNSAFE_ 前綴才能使用,以后可能會被徹底廢棄,不建議使用。

三、高階函數(shù)和函數(shù)柯里化的理解

1. 高階函數(shù)

如果一個函數(shù)符合下面2個規(guī)范中的任何一個,那么它就屬于一個高階函數(shù)

  1. 若A函數(shù),接收的參數(shù)是一個函數(shù),那么A就可以稱為高階函數(shù)
  2. 若A函數(shù),它的返回值依然是一個函數(shù),那么A就可以稱為高階函數(shù)

 常見的高階函數(shù):Promise,setTimeout,arr.map(數(shù)組方法)

2. 函數(shù)的柯里化

通過函數(shù)繼續(xù)調(diào)用,返回值為函數(shù)的方式,實現(xiàn)多次接受參數(shù),最后統(tǒng)一處理的函數(shù)編碼形式

function sum(a){
    return (b)=>{
        return (c)=>{
            return a + b + c
        }
    }
}
const result = sum(1)(2)(3)
console.log(result);

3. 使用函數(shù)柯里化代碼示例

class Login extends React.Component {
    // 初始化狀態(tài)
    state = {
        username:'', // 用戶名
        password:'', // 密碼
    }
    // 保存表單數(shù)據(jù)到狀態(tài)中
    saveFormDate=(dataType,event)=>{ // 標識當前標簽
        this.setState({[dataType]:event.target.value})
    }
    // 表單提交的回調(diào)
    handleSubmit=(event)=>{
        event.preventDefault(); // 阻止默認事件
        
        let {username,password} = this.state
        alert(`你輸入的用戶名是${username},密碼是${password}`)
    }
    render(){
        return(
            <div>
                <form action="https://www.baidu.com/" onSubmit={this.handleSubmit}>
                    用戶名:<input type="text" onChange={(event)=>this.saveFormDate('username',event)} name="username" />    
                    密碼:<input type="text" onChange={(event)=>this.saveFormDate('password',event)} name="password" />
                    <button type="submit">登錄</button>  
                </form>
            </div>
        )
    }
}

4. 不用函數(shù)柯里化代碼示例

class Login extends React.Component {
    // 初始化狀態(tài)
    state = {
        username:'', // 用戶名
        password:'', // 密碼
    }
    // 保存表單數(shù)據(jù)到狀態(tài)中
    saveFormDate=(dataType)=>{ // 標識當前標簽
        return (event)=>{ // 這里的回調(diào)誰執(zhí)行? input標簽的 onChange事件
            this.setState({[dataType]:event.target.value})
        }
    }
    // 表單提交的回調(diào)
    handleSubmit=(event)=>{
        event.preventDefault(); // 阻止默認事件
        
        let {username,password} = this.state
        alert(`你輸入的用戶名是${username},密碼是${password}`)
    }
    render(){
        return(
            <div>
                <form action="https://www.baidu.com/" onSubmit={this.handleSubmit}>
                    用戶名:<input type="text" onChange={this.saveFormDate('username')} name="username" />    
                    密碼:<input type="text" onChange={this.saveFormDate('password')} name="password" />
                    <button type="submit">登錄</button>  
                </form>
            </div>
        )
    }
}

總結(jié):

以上就是 React 面向組件編程(下),不懂得也可以在評論區(qū)里問我或私聊我詢問。

以上就是JavaScript中React 面向組件編程(下)的詳細內(nèi)容,更多關(guān)于React 面向組件編程的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • axios請求響應數(shù)據(jù)加解密封裝實現(xiàn)詳解

    axios請求響應數(shù)據(jù)加解密封裝實現(xiàn)詳解

    這篇文章主要為大家介紹了axios請求響應數(shù)據(jù)加解密封裝實現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-03-03
  • 基于React路由跳轉(zhuǎn)的幾種方式

    基于React路由跳轉(zhuǎn)的幾種方式

    這篇文章主要介紹了React路由跳轉(zhuǎn)的幾種方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • React常見跨窗口通信方式實例詳解

    React常見跨窗口通信方式實例詳解

    這篇文章主要為大家介紹了React常見跨窗口通信方式實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-10-10
  • React中Ref 的使用方法詳解

    React中Ref 的使用方法詳解

    這篇文章主要介紹了React中Ref 的使用方法,結(jié)合實例形式總結(jié)分析了react中ref基本功能、用法及操作注意事項,需要的朋友可以參考下
    2020-04-04
  • 淺談React高階組件

    淺談React高階組件

    這篇文章主要介紹了淺談React高階組件,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • React組件中監(jiān)聽函數(shù)獲取不到最新的state問題

    React組件中監(jiān)聽函數(shù)獲取不到最新的state問題

    這篇文章主要介紹了React組件中監(jiān)聽函數(shù)獲取不到最新的state問題問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • react中的useImperativeHandle()和forwardRef()用法

    react中的useImperativeHandle()和forwardRef()用法

    這篇文章主要介紹了react中的useImperativeHandle()和forwardRef()用法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • react-native 圓弧拖動進度條實現(xiàn)的示例代碼

    react-native 圓弧拖動進度條實現(xiàn)的示例代碼

    本篇文章主要介紹了react-native 圓弧拖動進度條實現(xiàn)的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-04-04
  • 簡單談談React中的路由系統(tǒng)

    簡單談談React中的路由系統(tǒng)

    下面小編就為大家?guī)硪黄唵握務凴eact中的路由系統(tǒng)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-07-07
  • react中使用usestate踩坑及解決

    react中使用usestate踩坑及解決

    這篇文章主要介紹了react中使用usestate踩坑及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08

最新評論