React 數據傳遞


React中的數據傳遞

  在 react 的學習過程中,少不了會遇到各個組件之間數據傳遞的問題,本文主要是在個人學習做項目過程中,對數據在 react 組件中傳遞的小總結。

  數據傳遞的流向:1、數據從父組件傳遞到子組件,2、數據從子組件傳遞到父組件,3、多個組件共享狀態數據。

  數據傳遞的方式:1、實例屬性 props,2、函數,3、狀態提升

  當然,context 也可以實現組件間的數據傳遞,官網對其的描述為: “使用React可以非常輕松地追蹤通過React組件的數據流,在有些場景中,你不想要向下每層都手動地傳遞你需要的 props. 這就需要強大的 context API了”。但是同樣也提到:“絕大多數應用程序不需要使用 context,如果你想讓你的應用更穩定,別使用context。因為這是一個實驗性的API,在未來的React版本中可能會被更改”。具體使用方法可到官網查看。本文提供代碼和注釋以及運行的結果圖,具體的代碼說明可查看注釋。

 

數據從父組件到子組件

  數據由父組件傳遞到子組件相對簡單,一般的處理方法是,在父組件中定義、獲取需要傳遞的數據,在父組件頁面中通過 <子組件名稱  props屬性名稱 = {傳遞的數據} />  傳遞,最后在子組件中使用 this.props.props對應的屬性名稱  即可接受父組件傳遞過來的數據。

一、將數據從父組件傳遞到子組件,數據傳遞過程中,注意父組件和子組件中各自屬性的名稱要對應

父組件代碼:

 

 1 var React = require('react');
 2 var ReactDOM = require('react-dom'); 3 import BodyChild from './components/indexchild'; 4 5 class Index extends React.Component { 6 7  constructor() { 8 //調用基類的所有的初始化方法 9  super(); 10 11 // 設置當前組件的屬性 12 this.state = { 13 username: "Guang", 14 age: 20 15  }; 16  }; 17 18  parentFunc(){ 19 alert("我是父組件中的 parentFunc 函數"); 20  } 21 22  render() { 23 return ( 24 <div> 25 <h3>父組件</h3> 26 27 {/* 顯示當前組件的屬性作為對照 */} 28 <p>age_parent: {this.state.age}</p> 29 <p>username: {this.state.username}</p> 30 31 <BodyChild 32 //將當前組件的 state.xxx 屬性傳遞給 子組件的 props.xxx_child 33 age_child={this.state.age} 34 username_child={this.state.username} 35 // 將 父組件的函數 this.parentFunc 傳遞給子組件 props.childFunc 36 childFunc={this.parentFunc.bind(this)} 37 /> 38 </div> 39  ); 40  } 41 } 42 43 ReactDOM.render( 44 <Index/>, document.getElementById('example'));

 

 

子組件代碼:

 1 import React from 'react';
 2 
 3 export default class BodyChild extends React.Component{ 4 5  constructor(props){ 6 // React組件的構造函數將會在裝配之前被調用。當為一個React.Component子類定義構造函數時, 7 // 你應該在任何其他的表達式之前調用super(props)。否則,this.props在構造函數中將是未定義,並可能引發異常 8  super(props); 9 10 // 父組件傳遞過來的屬性存儲在 props.username_child 中,將其賦值給當前組件的 state.username_child 11 this.state={username_child:props.username_child} 12  } 13 14  render(){ 15 return( 16 <div> 17 <h3>子組件</h3> 18 19 {/* 父組件傳遞過來的屬性存儲在 props.age_child 中,獲取並顯示屬性的值 */} 20 <p>age_child(通過 props 獲得): {this.props.age_child}</p> 21 22 {/* 獲取並顯示 state.username_child,該屬性的值是從父組件中獲取的 */} 23 <p>username_child(通過 props 賦值給 state 獲得): {this.state.username_child}</p> 24 25 {/* 這里獲取並執行父組件傳遞過來的函數 */} 26 {this.props.childFunc()} 27 </div> 28  ) 29  } 30 }

 

運行結果:

 

 

二、將數據從父組件傳遞到子組件,若有多個數據要傳遞,如1000個,可一次性傳遞,參數傳遞過程時,注意父組件和子組件中各自屬性的名稱,與前面代碼相比,下列代碼對應屬性名稱有所改變(父組件中的 state.xxx  在子組件中獲取的形式為 props.xxx)

父組件代碼

 1 var React = require('react');
 2 var ReactDOM = require('react-dom'); 3 import BodyChild from './components/indexchild'; 4 5 class Index extends React.Component { 6 7  constructor() { 8 //調用基類的所有的初始化方法 9  super(); 10 11 // 設置當前組件的屬性 12 this.state = { 13 username: "Guang", 14 age: 20 15  }; 16  }; 17 18  render() { 19 return ( 20 <div> 21 <h3>子組件</h3> 22 23 {/* 顯示當前組件的屬性作為對照 */} 24 <p>age_parent: {this.state.age}</p> 25 <p>username: {this.state.username}</p> 26 27 {/* 一次性傳遞當期組件的所有 state 中的屬性傳給子組件 同理:傳遞 props 可使用 {...this.props} */} 28 <BodyChild{...this.state}/> 29 30 </div> 31  ); 32  } 33 } 34 35 ReactDOM.render( 36 <Index/>, document.getElementById('example'));

 

子組件代碼

 1 import React from 'react';
 2 
 3 export default class BodyChild extends React.Component{ 4 5  constructor(props){ 6 // React組件的構造函數將會在裝配之前被調用。當為一個React.Component子類定義構造函數時, 7 // 你應該在任何其他的表達式之前調用super(props)。否則,this.props在構造函數中將是未定義,並可能引發異常 8  super(props); 9 10 // 父組件傳遞過來的屬性存儲在 props.username 中,將其賦值給當前組件的 state.username_child 11 this.state={username_child:props.username} 12  } 13 14  render(){ 15 return( 16 <div> 17 <h3>子組件</h3> 18 19 {/* 父組件傳遞過來的屬性存儲在 props.age 中,獲取並顯示屬性的值 */} 20 <p>age_child(一次性傳遞,通過 props 獲得): {this.props.age}</p> 21 22 {/* 獲取並顯示 state.username_child,該屬性的值是從父組件中獲取的 */} 23 <p>username_child(一次性傳遞,通過 props 賦值給 state 獲得): {this.state.username_child}</p> 24 25 </div> 26  ) 27  } 28 }

 

 運行結果:

 

 

  說完了數據從父組件到子組件的傳遞,接下來是數據從子組件到父組件,與前者相比,后者的相對復雜,其傳遞方式一般為:在子組件中通過調用父組件傳遞過來的事件函數進行數據的傳遞 ,即

  1、首先在父組件中定義一個函數(用於數據的傳遞,里面處理獲取的各項數據)

  2、將函數通過 “數據從父組件傳遞到子組件” 的方式將函數傳遞到子組件

  3、在子組件中通過事件綁定或着直接調用的方式執行函數(執行時可以傳入數據、事件等),最終實現數據的傳遞

 

數據從子組件到父組件

 

例1:直接傳遞數據

父組件代碼:

 1 var React = require('react');
 2 var ReactDOM = require('react-dom'); 3 import BodyChild from './components/indexchild'; 4 class Index extends React.Component { 5  constructor() { 6 super(); //調用基類的所有的初始化方法 7 this.state = { 8 username: "Tom", 9 age: 20, 10 child_data:"子組件的輸入在此顯示", 11 }; //初始化賦值 12  }; 13 14  parentGetData(child_username,child_age){ 15 this.setState({child_username:child_username,child_age:child_age}); 16 // console.log(child_username,child_age); 17  } 18 19  render() { 20 return ( 21 <div> 22 <h3>子組件的信息 用戶名為:Guang Zai 年齡為:18 開始時為空,點擊按鈕可獲取</h3> 23 <p>子組件用戶名:{this.state.child_username}</p> 24 <p>子組件年齡:{this.state.child_age}</p> 25 <BodyChild childGetData={(n1,n2)=>this.parentGetData(n1,n2)}/> 26 </div> 27  ); 28  } 29 } 30 ReactDOM.render( 31 <Index/>, document.getElementById('example'));

 

子組件代碼:

 1 import React from 'react';
 2 
 3 export default class BodyChild extends React.Component{ 4 5  constructor(props){ 6 // React組件的構造函數將會在裝配之前被調用。當為一個React.Component子類定義構造函數時, 7 // 你應該在任何其他的表達式之前調用super(props)。否則,this.props在構造函數中將是未定義,並可能引發異常 8  super(props); 9 this.state={ 10 username:"Guang Zai", 11 age:18 12  } 13  } 14  render(){ 15 return( 16 <div> 17 <p>子組件按鈕:<input type="button" value="點擊獲取子組件信息" onClick={()=>this.props.childGetData(this.state.username,this.state.age)}></input></p> 18 </div> 19  ) 20  } 21 }

 

運行結果:

 

 

例2:通過事件傳遞數據

父組件代碼:

 1 var React = require('react');
 2 var ReactDOM = require('react-dom'); 3 import BodyChild from './components/indexchild'; 4 class Index extends React.Component { 5  constructor() { 6 super(); //調用基類的所有的初始化方法 7 this.state={child_data:"此處實時顯示子組件輸入的信息"} 8 9 // 初始化時 函數 this 使用 bind 綁定當前類 10 this.parentPageInputBind=this.parentPageInputBind.bind(this); 11  }; 12 13  parentPageInputBind(e){ 14 this.setState({child_data:e.target.value}); 15  }; 16 17  render() { 18 return ( 19 <div> 20 <h3>子組件實時輸入的信息</h3> 21 <p>實時輸入的信息:{this.state.child_data}</p> 22 <BodyChild childPageInputBind={this.parentPageInputBind}/> 23 </div> 24  ); 25  } 26 } 27 ReactDOM.render( 28 <Index/>, document.getElementById('example'));

 

子組件代碼:

 1 import React from 'react';
 2 
 3 export default class BodyChild extends React.Component{ 4  render(){ 5 return( 6 <div> 7 <p>子組件輸入:<input type="text" onChange={this.props.childPageInputBind}></input></p> 8 </div> 9  ) 10  } 11 }

 

運行結果:

 

 

多個組件共享狀態數據

綜合上述參數的雙向傳遞,通過將多個子組件輸入的數據傳遞到同一個父組件,然后將該父組件中處理好的數據傳遞回給需要的子組件,實現數據間的共享

 1 import React from 'react';
 2 
 3 class LettersInput extends React.Component{
 4   constructor(props){
 5     super(props);
 6   }
 7   handleChange(e){
 8     this.props.onLettersChange(e);
 9   }
10   render(){
11     const letters=this.props.letters;
12     return(
13       <div>
14         <input value={letters} onChange={(e)=>this.handleChange(e)}></input>
15       </div>
16     )
17   }
18 }
19 
20 class AppComponent extends React.Component {
21   constructor(props){
22     super(props);
23     this.state={letters:''};
24     this.handleChange=this.handleChange.bind(this);
25   }
26 
27   handleChange(e){
28     const letters=e.target.value;
29     const last=letters.substr(letters.length-1,1);
30     if(/[^a-z]/i.test(last)){
31       return '';
32     }
33     this.setState({letters:letters});
34   }
35 
36   render(){
37     const letters=this.state.letters;
38     return(
39       <div>
40         <span>lower case letter:</span><LettersInput letters={letters.toLowerCase()} onLettersChange={this.handleChange}/>
41         <span>upper case letter:</span><LettersInput letters={letters.toUpperCase()} onLettersChange={this.handleChange}/>
42       </div>
43     )
44   }
45 
46 }
47 
48 AppComponent.defaultProps = {
49 };
50 
51 export default AppComponent;

運行結果:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM