在 React 父子組件、非父子組件間傳遞數據

React 是 Facebook 創造的 JavaScript 庫。雖然在 React 中處理數據顯得有點複雜,但其實並無那麼棘手。最近我總結了三種在 React 中進行數據處理的方法:react

  1. 使用 Props 從父組件傳遞數據到子組件
  2. 使用回調函數從子組件傳遞數據到父組件
  3. 非父子組件之間傳遞數據:
    • 結合 Props 和回調函數
    • 使用 Redux 傳遞數據
    • 使用 React Context API 傳遞數據

這篇文章中主要總結了這些實現方式,新手能夠從中縱覽全局。編程

使用 Props 從父組件傳遞數據到子組件

假設咱們的目錄結構以下所示:redux

App
└── Parent
    ├── Child1
    └── Child2

這是 React 中最簡單也是最基礎的數據流向。api

class Parent extends React.Component {
	state = { data : "Hello World" } 
	render() {
        return (
            <div>
                 <Child1/> // 無數據傳遞           
                 <Child2 dataFromParent = {this.state.data} />
            </div>
        );
    }
}
// 沒有強制要求必須傳遞 state 中的值,經過 var 或者 const 定義的變量也能夠從父組件傳遞給子組件

在子組件中,能夠很是簡單地使用 this.props.dataFromParent (只是一個經過 props 傳遞的變量) 來獲取到從父組件傳遞過來的數據。ide

class Child2 extends React.Component {
	render() {
        return (
            <div>
                The data from parent is:{this.props.dataFromParent}
            </div>
        );
    }
}

使用回調函數從子組件傳遞數據給父組件

若是我要從 Child1 子組件中傳遞信息——「美女,最近還好嗎?」 給父組件,應該怎麼作呢?爲了實現這個目的,須要按照如下步驟進行操做:函數式編程

第一步:在父組件中定義一個有參數的回調函數函數

第二步:將該回調函數做爲 Props 傳遞到 Child1 子組件this

class Parent extends React.Component {
	state = { message: "" }
	callbackFunction = (childData) => {
      this.setState({message: childData})
	},
	render() {
        return (
            <div>
                 <Child1 parentCallback = {this.callbackFunction}/>
                 <p> {this.state.message} </p>
            </div>
        );
	}
}

第三步:在子組件中,經過調用 this.props.callback(dataToParent) 將數據 dataToParent 傳遞給父組件spa

class Child1 extends React.Component{
	sendData = () => {
         this.props.parentCallback("美女,最近還好嗎?");
    },
	render() { 
		//在想傳遞信息給父組件的任意時刻調用 sendData 方法
    }
};

非父子組件之間傳遞數據

當我仍是一個初學者的時候,選擇哪一種方式進行非父子組件間通信對我來講是一個難題。如今我知道有如下三種方式,而且每種方式都有本身的優缺點。code

方式1:結合 Props 和回調函數

這種方式不適用複雜的組件樹,由於這將有一大部分進行數據傳遞的代碼要寫,並且須要中間層進行數據的傳遞,雖然可能它們並不須要該數據。

方式2:使用 Redux 傳遞數據

方式3:使用 React Context API 傳遞數據

如今有不少關於爲何 React 加強了 Context API 以及在何場景下哪一種方式更優的文章。如下是兩篇推薦:

React Context API — A Replacement for Redux?

You Might Not Need Redux

我使用過這種方式,相比 Redux,我更傾向於使用該方式。

Context API 的最大優點是:這種方式使開發者從 「Prop 深淵」中解放出來。(Props 深淵是指傳遞數據到子組件中。主要的思路是函數式編程,不斷地將參數傳遞給下一個函數)

建設咱們有如下的組件樹,想要從 Child1 中傳遞信息「SSup brother?」給組件 Child2。

App
├── Child1
└── Child2

第一步:爲兩個子組件建立一個 Provider

這個 Provider 管理 state 並返回一個 contextObject.Provider 組件。

第二步:在 Provider 組件中,使用 props 傳遞 state 和回調函數

export const MContext = React.createContext(); 
// 導出 context 對象
class MyProvider extends Component {
	state = {message: ""}
	render() {
        return (
            <MContext.Provider value={
            	{
                    state: this.state,
                	setMessage: (value) => this.setState({message: value })}}>
            {this.props.children}   // 這裏顯示全部的子組件均可以訪問全局的 store
            </MContext.Provider>)
    }
}

provider 是全部子組件共享的(一個全局的store,保存了全部 state 和一個操做這些 state 的回調函數)。任何須要這些狀態的組件都須要先和 provider 打交道。

(a) 在 Child1 中經過 provider 中的 setMessage 處理信息

(b) 在 Child2 中經過 provider 獲取信息

第三步:將 MyProvider 當作 Child1 和 Child2 兩個組件的父組件

class App extends React.Component {
	render() {
        return (
            <div>
                 <MyProvider>
                      <div className="App">
                      <Child1/>
                      <Child2/>
                      </div>
               </MyProvider>
            </div>
        );
	}
}

第四步:Child1 和 Child2 都是 Provider 的消費者,進而都須要經過使用 Consumer 標籤來與 Provider 打交道。

import MContext
class Child1 extends React.Component {
	render() {
    	return (
        	<div>
        		<Mcontext.Consumer>
        			{(context) => (
      					<button onClick={()=>{context.setMessage("New Arrival")}}>Send</button>
       				)}
        		</Mcontext.Consumer>
        	</div>
    	)
    }
}

Child2 中如何接收這些數據呢?

也是用 Consumer 標籤與 Provider 打交道。

import MContext
class Child2 extends React.Component {
	render() {
       return (
         <div>
            <Mcontext.Consumer>
            	{(context) => (
              		<p>{context.state.message}}</p>
                )}
            </Mcontext.Consumer>
         </div>
   		)
    }
}

但願上面的描述比較清晰的解釋瞭如何在 React 中進行大量組件的數據傳遞。

推薦閱讀:

Using Context in React

相關文章
相關標籤/搜索