zoukankan      html  css  js  c++  java
  • 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;

    运行结果:

  • 相关阅读:
    Lucene搜索引擎例子demo
    java Log4j日志配置详解大全
    java获取当前上一周、上一月、上一年的时间
    Django组件-cookie与session
    前端基础之jQuery
    Django组件-forms
    Django组件-分页器
    Django-Ajax
    Django模型层-多表操作
    Django模型层-单表操作
  • 原文地址:https://www.cnblogs.com/go4it/p/9553859.html
Copyright © 2011-2022 走看看