原生React组件的数据传输管理

原生React组件之间的数据传输主要依赖于两个关键词:属性(props) 和状态(state)。每一个组件都是一个对象,props是对象的一个属性,组件对象可以通过props进行传递。React 的核心思想是组件化的思想,应用由组件搭建而成,而组件中最重要的概念是State(状态),State是一个组件的UI数据模型,是组件渲染时的数据依据。state与props的最大区别在于props是不可变的而state是可变的。具体内容后面会详细讲解。

原生React组件之间数据传递场景可以分为以下四种: 
- 组件内部的数据传输 
- “父组件”向“子组件”传值 
- “子组件”向 “父组件”传值 
- “兄弟组件”之间的传值

1、组件内部的数据传输
  在初学过程的项目开发中常常会有去尝试DOM操作的冲动,虽然大部分情况下这种尝试是错误的,但是在某些时候还是不得不需要获取对DOM的值进行操作。例如:点击一个按钮之后触发一个点击事件,让一个input文本框获得焦点。jQuery开发者的第一反应肯定是给button绑定点击事件,然后在事件中通过$(‘select’)获取到要操作的节点,再给节点添加焦点。然而在React中这种操作是不允许的,而React中应该怎么做呢?

React Refs属性:

import React, { Component } from 'react';

class MyComponent extends Component({
  handleClick = () => {
    // 使用原生的 DOM API 获取焦点
    this.refs.myInput.focus();
  },
  render: function() {
    //  当组件插入到 DOM 后,ref 属性添加一个组件的引用于到 this.refs
    return (
      <div>
        <input type="text" ref="myInput" />
        <input
          type="button"
          value="点我输入框获取焦点"
          onClick={this.handleClick}
        />
      </div>
    );
  }
});

ReactDOM.render(
  <MyComponent />,
  document.getElementById('example')
);

我们可以从上面的代码当中看到 其中的ref在功能上扮演起了一个标识符(id)的角色,this.refs.myInput.focus()也有一种document.getElementById(‘myInput’).focus()的味道。

  上面的操作我们也称为React表单事件,React表单事件中除了ref具有关键作用外,还有另一个关键参数’event’。例如:当我需要实时获取到一个文本框里面的内容,然后进行一个判断,当满足某个条件的时候触发另一个事件。这个时候就需要使用到这个一个关键参数’event’。

React 表单事件-event参数:

class MyComponent extends Component{
    handleChange = (event) => {
        if(event.target.value === 'show'){
            console.log(this.refs.showText);
        }
    };
    render(){
        return(
            <div>
                <input type="text" onChange={this.handleChange}/>
                <p ref='showText'>条件满足我就会显示在控制台</p>
            </div>

        )

    }
}
export default MyComponent;

 

上面实例实现的效果就是,通过event.target.value获取当前input中的内容,当input中输入的内容是show的时候,控制台就将ref为showText的整个节点内容打印出来。从这个实例当中我们也看到了,event作为一个默认参数将对应的节点内容进行了读取。

  因此在组件内部涉及的DOM操作数据传递主要就是这两种方式,可以根据不同的场景选择不同的方式。虽然ref适用于所有组件元素,但是ref在正常的情况下都不推荐使用,后面会进行介绍通过 state管理组件状态,避免进行DOM的直接操作。

2、“父组件”向“子组件”传值
  父组件与子组件之间的通信通常使用props进行。具体如下:

import React,{ Component } from 'react'

class ChildComponent extends Component{
    render (){
        return (
            <div>
                <h1>{this.props.title}</h1>
                <span>{this.props.content}</span>
            </div>
        )
    }
}
class ParentComponent extends Component {
    render (){
        return (
            <div>
                <ChildComponent title="父组件与子组件的数据传输测试" content="我是传送给子组件span中显示的数据" />
                <p>我是父组件的内容</p>
            </div>
        )
    }
}

export default ParentComponent;

上面示例展示了父组件向子组件传递了两个props属性分别为title和content,子组件通过this.props获取到对应的两个属性,并将其展示出来,这个过程就是一个父与子组件之间的数据交互方式。但是也可以从例子中看到props的值是不变的,父传给子什么样的props内容就只能接收什么样的使用,不能够在子中进行重新赋值。

3、“子组件”向 “父组件”传值
  本例中将会引入了管理组件状态的state,并进行初始化。具体如下:

import React, { Component } from 'react';
//子组件
class Child extends Component {
    render(){
        return (
            <div>
                请输入邮箱:<input onChange={this.props.handleEmail}/>
            </div>
        )
    }
}
//父组件,此处通过event.target.value获取子组件的值
class Parent extends Component{
    constructor(props){
        super(props);
        this.state = {
            email:''
        }
    }
    handleEmail = (event) => {
        this.setState({email: event.target.value});
    };
    render(){
        return (
            <div>
                <div>用户邮箱:{this.state.email}</div>
                <Child name="email" handleEmail={this.handleEmail}/>
            </div>
        )
    }
}

export default Parent;

通过上面的例子可以看出”子组件”传递给”父组件”数据其实也很简单,概括起来就是:react中state改变了,组件才会update。父写好state和处理该state的函数,同时将函数名通过props属性值的形式传入子,子调用父的函数,同时引起state变化。子组件要写在父组件之前。

从本示例中也可以看出state可以通过setState进行重新赋值,因此state是可变的,表示的是某一时间点的组件状态。

4、“兄弟组件”之间的传值
  当两个组件不是父子关系,但有相同的父组件时,将这两个组件称为兄弟组件。严格来说实际上React是不能进行兄弟间的数据直接绑定的,因为React的数据绑定是单向的,所以才能使得React的状态处于一个可控的范围。对于特殊的应用场景中,可以将数据挂载在父组件中,由两个组件共享:如果组件需要数据渲染,则由父组件通过props传递给该组件;如果组件需要改变数据,则父组件传递一个改变数据的回调函数给该组件,并在对应事件中调用。从而实现兄弟组件之间的数据传递。

import React, { Component } from 'react';
//子组件
class Child extends Component {
    render(){
        return (
            <div>
                我是子组件邮箱:<input onChange={this.props.handleEmail} defaultValue={this.props.value} />
            </div>
        )
    }
}
//兄弟组件
class ChildBrother extends Component {
    render(){
        return (
            <div>
                我是兄弟组件:{this.props.value}
            </div>
        )
    }
}
//父组件,此处通过event.target.value获取子组件的值
class Parent extends Component{
    constructor(props){
        super(props);
        this.state = {
            email:''
        }
    }
    handleEmail = (event) => {
        this.setState({email: event.target.value});
    };
    render(){
        return (
            <div>
                <div>我是父组件邮箱:{this.state.email}</div>
                <Child handleEmail={this.handleEmail} value={this.state.email}/>
                <ChildBrother value={this.state.email}/>
            </div>
        )
    }
}

export default Parent;

上面例子中就是child组件的值改变后存储在父组件的state中,然后再通过props传递给兄弟组件childBrother。从而实现兄弟组件之间的数据传递。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值