天天看點

ReactP7_React的元件化開發(二)_super(props)傳值問題_元件通信子傳父_Context關于super(props)的傳值問題元件通信子傳父元件通信案例Context

ReactP7_React的元件化開發(二)

  • 關于super(props)的傳值問題
  • 元件通信子傳父
  • 元件通信案例
  • Context
    • React.createContext
    • Context.Provider
    • Class.contextType
    • Context.Consumer

這邊是react學習記錄,期間加入了大量自己的了解,用于加強印象,若有錯誤之處還請多多指出

關于super(props)的傳值問題

ReactP7_React的元件化開發(二)_super(props)傳值問題_元件通信子傳父_Context關于super(props)的傳值問題元件通信子傳父元件通信案例Context

正常情況下,需要super(props)方法來擷取傳入此元件的參數。如圖所示,super( )方法并沒有去主動擷取props中的參數,是以在随後的console.log(this.props)中列印出來的是undefined,但是在render函數中,卻可以獲得props值,擷取值和super( )沒有關系。這個原因,需要從源碼中去解讀。架構不論我們是否主動擷取并指派this.props值,都會在運作的過程中進行一次對this.props的指派操作,是以在随後是可以直接使用傳過來的props參數的。具體代碼的位置在如圖所示的代碼中

ReactP7_React的元件化開發(二)_super(props)傳值問題_元件通信子傳父_Context關于super(props)的傳值問題元件通信子傳父元件通信案例Context

元件通信子傳父

某些情況,我們也需要子元件向父元件傳遞消息:

在vue中是通過自定義事件來完成的——this.$emit([自定義事件名])

在React中同樣是通過props傳遞消息,隻是讓父元件給子元件傳遞一個回調函數,在子元件中調用這個函數即可

個人了解來看,就是告訴子元件一些資訊“A={func}”,其中A是發生的事件名稱,func是發生該事件之後需要執行的事情,或者說需要執行的函數,子元件如果需要了,就會在發生指定的情況之後執行以下A,那麼就會在父元件根據A觸發的情況,執行以下func。和vue不同的是,vue是子元件告訴父元件發生了事情A,然後在A執行func,React是父元件告訴子元件A和func,然後子元件發生并使用了A,對應的調用了父元件之前給的的func

Appjs代碼

import React,{ Component } from "react";
import Child from "./Child"

export default class App extends Component{
    constructor(props){
        super();
        this.state = {
            counter:0
        }
        
    }
    
    render(){
        const {counter} = this.state;
        return (
            <div>
                <h2>{counter}</h2>
                <Child add = { e=>{this.Increment()}}/>
            </div>
        )
    }

    Increment(){
        this.setState({
            counter:this.state.counter + 1,
        })
    }
}
           

Childjs代碼

import React , {Component} from "react";

export default class Child extends Component{
    constructor(props){
        super(props);
        this.state = {

        }
    }

    render(){
        const { add } = this.props;
        return(
            <button onClick={add}>+1</button>
        )
    }
}
           

通俗的講:此處就是父元件寫了方法Increment,并且告訴子元件,發生add事件的話我就會執行Increment,子元件在發生點選事件之後,告訴父元件,發生了add事件需要執行Increment,此時父元件執行了一次Increment函數。基本就是這麼個思路

元件通信案例

ReactP7_React的元件化開發(二)_super(props)傳值問題_元件通信子傳父_Context關于super(props)的傳值問題元件通信子傳父元件通信案例Context

制作一個類似于tab的點選顯示效果:直接上代碼

App.js

import React,{ Component } from "react";
import TabControl from "./TabControl"


export default class App extends Component{
    constructor(props){
        super();
        console.log(this.props);//undefined
        this.state = {
            titles:["A","B","C"],
            currentIndex:0,
        }
        
    }
    
    render(){
        console.log(this.props);//{}
        const { titles, currentIndex } = this.state;
        return (
            <div>
                <TabControl itemClick={ index => { this.itemClick(index) }} titles={titles}/>
                <h2>{titles[currentIndex]}</h2>
            </div>
        )
    }

    itemClick(index){
        this.setState({
            currentIndex:index
        })
    }
}
           

tabControl.js

import React from "react";
import PropTypes from "prop-types"

export default class TabControl extends React.Component{
    constructor(props){
        super(props);
        this.props = props;
        this.state = {
            currentIndex : 0,
        }
    }

    render(){
        const { titles } = this.props;
        const { currentIndex } = this.state;
        return (
            <div className="tab-control">
                {
                    titles.map((item,index)=>{
                        return(
                            <div key={item} 
                                 className={"tab-item " + (index === currentIndex?"active":"")} 
                                 onClick={ e => { this.itemClick(index) }}>
                                <span>{item}</span>
                            </div>
                        )
                    })
                }
            </div>
        )
    }

    itemClick(index){
        this.setState({
            currentIndex:index,
        })

        const { itemClick } = this.props;
        itemClick(index);
    }
}

TabControl.propTypes = {
    titles:PropTypes.array,
    currentIndex:PropTypes.number,
}
           

style.css

*{
    margin: 0;
    padding: 0;
}
.tab-control{
    display: flex;
    text-align: center;
    height: 44px;
    line-height: 44px;
}
.tab-item{
    flex: 1;
}
.tab-item span{
    padding: 8px 5px;
}
.tab-item.active span{
    border-bottom: solid 2px red;
}
           

通過這個案例,基本能夠掌握元件通信了,而且這個難度的練習基本能夠應付很多的tab功能需求

Context

這一塊說實話很煩,我也記不太住,大緻了解成有那麼一個框框,這個框框表示的是那些可以被共享的參數,那些被框框給框住的元件,是可以通路到這些共享參數的,具體執行有興趣可以往下看

背景:常見的資料傳遞方式是通過props屬性自上而下(由父到子)進行傳遞,但是一些資料需要在多個元件中進行共享。如果在頂層的App中定義這些資訊,一層層傳遞下去,那麼對于一些中間元件不需要資料的元件來說,是一種備援的操作

Context 提供了一種在元件之間共享此類值的方式,而不必顯式地通過元件樹的逐層傳遞 props,Context 設計目的是為了共享那些對于一個元件樹而言是“全局”的資料。

簡而言之就是提供一種平台,能夠存放供所有元件共同讀取的資料,類似Vuex裡面$store.state青春版

React.createContext

  • 建立一個需要共享的Context對象

如果一個元件訂閱了Context,那麼這個元件會從離自身最近的那個比對的 Provider 中讀取到目前的context值

defaultValue是元件在頂層查找過程中沒有找到對應的Provider,那麼就使用預設值

個人了解:建立一個共享資料的框框, 共享的預設資料使用defaultValue存放

ReactP7_React的元件化開發(二)_super(props)傳值問題_元件通信子傳父_Context關于super(props)的傳值問題元件通信子傳父元件通信案例Context

Context.Provider

每個 Context 對象都會傳回一個 Provider React 元件,它允許消費元件訂閱 context 的變化

Provider 接收一個 value 屬性,傳遞給消費元件

一個 Provider 可以和多個消費元件有對應關系

多個 Provider 也可以嵌套使用,裡層的會覆寫外層的資料

當 Provider 的 value 值發生變化時,它内部的所有消費元件都會重新渲染

個人了解,這裡面存放的就是框框内部需要共享的資料

ReactP7_React的元件化開發(二)_super(props)傳值問題_元件通信子傳父_Context關于super(props)的傳值問題元件通信子傳父元件通信案例Context

這裡的"…"隻是表示需要輸入的是資料

Class.contextType

挂載在 class 上的 contextType 屬性會被重指派為一個由 React.createContext() 建立的 Context 對象

這能讓你使用 this.context 來消費最近 Context 上的那個值

你可以在任何生命周期中通路到它,包括 render 函數中

ReactP7_React的元件化開發(二)_super(props)傳值問題_元件通信子傳父_Context關于super(props)的傳值問題元件通信子傳父元件通信案例Context

Context.Consumer

這裡React 元件也可以訂閱到 context 變更。這能讓你在 函數式元件 中完成訂閱 context

這裡需要 函數作為子元素(function as child)這種做法

這個函數接收目前的 context 值,傳回一個 React 節點

consumer就是框框裡面需要調用資料的元件,需要套在Provider的裡面,通過回調函數來對資料進行調用

ReactP7_React的元件化開發(二)_super(props)傳值問題_元件通信子傳父_Context關于super(props)的傳值問題元件通信子傳父元件通信案例Context

以上就是元件化開發第二部分的全部内容了

感謝coderwhy(王紅元老師)的課程指導

愛生活,愛豬豬