react组件传值

1.父组件向子组件传值

方法:(通过props来传值,这种应用,很多时候我们某个组件在不同的地方用到,但是就只是内容不一样,这样在调用组件就是父组件的时候给各自自己的值就好)

父组件:

import React, { Component } from 'react'
import Es6cComponent from "../../company/index"
export default class index extends Component {
    render() {
        return (
            <div>
                 <Es6cComponent nameall="abc"/>
            </div>
        )
    }
}

子组件:

import React, { Component } from 'react'
export default class index extends Component {
    render() {
        return (
            <div>
             <div>{this.props.nameall}</div>
            </div>
        )
    }
}

2.子组件给父组件传值 

方法:将父组件的改变状态的方法传入子组件的props,绑定给子组件中的某些触发事件譬如按钮的点击,输入框输入等等,得到子组件的值或状态或动作,再调用父组件的方法得到子组件中的值。【props接受并执行

子组件:

import React, { Component } from 'react'

export default class index extends Component {
    //此方法改变父元素的背景色
    setData = () => {
        //此函数必须和父组件中的函数一样,将要改成什么颜色传给父组件,来改变父元素的值
        //接收并执行此函数
        this.props.changeColor("green")
    }
    render() {
        return (
            <div>
                <div>父元素的颜色====={this.props.bgColor}</div>
                <button onClick={this.setData}>改变父元素的背景色</button>
            </div>
        )
    }
}

父组件:

import React, { Component } from 'react'
import Es6cComponent from "../../company/index"
export default class index extends Component {
    state={
        bgColor:"#999"
    }
    //修改在父组件中修改哦哦【注意】
    baChange=(color)=>{
       console.log(color)
       this.setState({
           bgColor:color
       })
   }
    render() {
        return (
            <div style={{background:this.state.bgColor}}>
                {/* changeColor为父组件传给子组件传值方法 */}
                 <Es6cComponent title={this.state.bgColor} changeColor={(color)=>{this.baChange(color)}}/>
            </div>
        )
    }
}

3、兄弟组件传值

方法1:bus

React 中组件与通过 bus 、 bus.emit(‘xx’,{data})、 bus.on(‘xx’,data=>{}) 来传值;传值的组件用 bus.emit(‘xx’,{data})传值,接收值的组件用 bus.on(‘xx’,data=>{}) 来接收传来的值

bus.js代码:

import {EventEmitter} from 'events'

const bus = new EventEmitter()

export default bus;

子组件1:

import React, { Component } from 'react'
import bus from '../utis/bus' /*一定要导入bus */

export default class Brother1 extends Component {

    // dom节点渲染完毕
    componentDidMount(){
        //接收brother2传来的值
        bus.on('sendVal',data=>{
            console.log(data)
        })
    }
    //向brother2传值
    sendValueBrother2 = ()=>{
        bus.emit('sendValue',{
            name:'赵敏',
            age:600
        })
    }
    render() {
        return (
            <div>
                <h3>兄弟1组件</h3>
                <button onClick={this.sendValueBrother2}>传值给兄弟2</button>
            </div>
        )
    }
}

子组件2:

import React, { Component } from 'react'
import bus from '../utis/bus' /*一定要导入bus */

export default class Brother2 extends Component {
    
     //向brother1传值
    sendValueBrother1 = ()=>{
        bus.emit('sendVal',{
            name:'周芷若',
            age:600
        })
    }
    // dom节点渲染完毕
    componentDidMount(){
        //接收brother1传来的值
        bus.on('sendValue',data =>{
            console.log(data)
        })
    }

    render() {
        return (
            <div>
                <h3>兄弟2组件</h3> <br/>
                <button onClick={this.sendValueBrother1}>传值给兄弟1</button>

            </div>
        )
    }
}

父组件:

import React, { Component } from 'react'
import Es6cComponent from "../../company/index"
import Children from '../../company/oo'
export default class index extends Component {
  
    render() {
        return (
            <div >
                 {/* 子组件1 */}
                 <Es6cComponent />
                 {/* 子组件2 */}
                 <Children></Children>
            </div>
        )
    }
}

方法2:事实上是将一些共同的状态存入一个更高的组件中存放着,从这个地方操作值和调用值【类似于子传父】

子组件1:

import React, { Component } from 'react'

export default class index extends Component {
    changefun=()=>{
        this.props.changeChild2Color("green");
    }
    
    render() {
        return (
            <div>
                <div>子组件1</div>
                <button onClick={()=>{this.changefun()}}>改变子组件2的背景色</button>
            </div>
        )
    }
}

子组件2:

import React, { Component } from 'react'

export default class oo extends Component {
    render() {
        return (
            <div style={{background:this.props.bgColor}}>
                {/* 从父元素获取自己的背景色 */}
                <div>子组件2的背景:{this.props.bgColor}</div>
                
            </div>
        )
    }
}

父组件:

import React, { Component } from 'react'
import Es6cComponent from "../../company/index"
import Children from '../../company/oo'
export default class index extends Component {
state={
    child2color:"#999",
}
changcolor2=(color)=>{
    this.setState({
        child2color:color
    })
}
    render() {
        return (
            <div >
                 {/* 子组件1 */}
                 <Es6cComponent  changeChild2Color={(color)=>{this.changcolor2(color)}}/>
                 {/* 子组件2 */}
                 <Children bgColor={this.state.child2color}></Children>
            </div>
        )
    }
}

4.跨级组件

所谓跨级组件通信,就是父组件向子组件的子组件通信,向更深层的子组件通信。跨级组件通信可以采用下面两种方式:

  • 中间组件层层传递 props
  • 使用 context 对象

对于第一种方式,如果父组件结构较深,那么中间的每一层组件都要去传递 props,增加了复杂度,并且这些 props 并不是这些中间组件自己所需要的。不过这种方式也是可行的,当组件层次在三层以内可以采用这种方式,当组件嵌套过深时,采用这种方式就需要斟酌了。 

使用 context 是另一种可行的方式,context 相当于一个全局变量,是一个大容器,我们可以把要通信的内容放在这个容器中,这样一来,不管嵌套有多深,都可以随意取用。
使用 context 也很简单,需要满足两个条件:

  • 上级组件要声明自己支持 context,并提供一个函数来返回相应的 context 对象
  • 子组件要声明自己需要使用 context

在使用 context 时,需要注意:

父组件需要声明自己支持 context,并提供 context 中属性的 PropTypes
子组件需要声明自己需要使用 context,并提供其需要使用的 context 属性的 PropTypes
父组件需提供一个 getChildContext 函数,以返回一个初始的 context 对象


如果组件中使用构造函数(constructor),还需要在构造函数中传入第二个参数 context,并在 super 调用父类构造函数是传入 context,否则会造成组件中无法使用 context。
如果要改变context对象,需要将其与父组件的state或者props相关联,通过改变该父组件的state或者props来改变context。在父组件的 state 或 props 变化时,会自动调用 getChildContext 方法,返回新的 context 对象,而后子组件进行相应的渲染。

父组件:home.js


import React, { Component } from 'react';
//父组件需要声明自己支持 context,并提供 context 中属性的 PropTypes
import PropTypes from "prop-types";
//引入子组件
import Sub from "../../company/sub";
export default class index extends Component {
    //上级组件要声明自己支持 context,并提供一个函数来返回相应的 context 对象
    // 父组件声明自己支持 context
    static childContextTypes = {
        color: PropTypes.string,
        callback: PropTypes.func,
    }
    //父组件需提供一个 getChildContext 函数,以返回一个初始的 context 对象
    // 父组件提供一个函数,用来返回相应的 context 对象
    getChildContext() {
        return {
            color: "red",
            callback: this.callback.bind(this)
        }
    }

    callback(msg) {
        console.log(msg)
    }

    render() {
        return (
            <div>
                <Sub></Sub>
            </div>
        );
    }
}

子组件:sub.js

import React from "react";
import SubSub from "./subsub";

const Sub = (props) =>{
    return(
        <div>
            <SubSub />
        </div>
    );
}

export default Sub;

子组件中的子组件:subsub.js

import React, { Component } from "react";
//子组件需要声明自己需要使用 context,并提供其需要使用的 context 属性的 PropTypes
import PropTypes from "prop-types";

export default class SubSub extends Component {
    // 子组件声明自己需要使用 context
    static contextTypes = {
        color: PropTypes.string,
        callback: PropTypes.func,
    }
    render() {
        console.log(this.context)
        //方法一:
        const style = { color: this.context.color }
        console.log(style);//打印得到
        //方法二:
        // let {style}=this.context.color;
        // console.log(style);//打印不到
        const cb = (msg) => {
            console.log(msg)
            return () => {
                this.context.callback(msg);
            }
        }
        return (
            <div style={style}>
                SUBSUB
                <button onClick={cb("我胡汉三又回来了!")}>点击我</button>
            </div>
        );
    }
}

5.非嵌套组件

就是没有任何包含关系的组件,包括兄弟组件以及不在同一个父级中的非兄弟组件。对于非嵌套组件,可以采用下面两种方式:

  • 利用二者共同父组件的 context 对象进行通信
  • 使用自定义事件的方式

第一种方式所使用的context对象类似一个全局变量,有可能会造成全局污染。[不推荐]

先安装:

npm install event -S

 组件结构: App组件为根组件,根组件里面有两个兄弟组件,foo,boo, 用于在foo和boo组件进行通信的Event服务.下面实现foo组件与boo组件之间的通信

event.js

//向外提供一个事件对象
import { EventEmitter } from "events";
export default new EventEmitter();

home.js

import React, { Component } from 'react';
import Foo from "../foo";
import Boo from "../boo";
export default class App extends Component{
    render(){
        return(
            <div className="App">
            <header className="App-header">
              <h1 className="App-title">Welcome to React</h1>
            </header>
            <Foo />
                <Boo />
          </div>

        );
    }
}


boo.js

import React,{ Component } from "react";
import emitter from "../utis/event"

export default class Boo extends Component{
    constructor() {
        super();
        this.handleClick = this.handleClick.bind(this);
    }
    handleClick() {
        emitter.emit('callMe', 'Hello');
    }
    render() {
        return (
            <button onClick={this.handleClick}>点我</button>      
        );
    }

}

 foo.js

import React,{ Component } from "react";
import emitter from "../utis/event"

export default class Foo extends Component{
    constructor() {
        super();
    }
    componentDidMount() {
        this.eventEmitter = emitter.on('callMe', (msg) => {
            alert(msg);
        });
    }
    componentWillUnmount() {
        emitter.removeListener(this.eventEmitter);
    }
    render() {
        return (
            <p>Parent Component</p>
        );
    }

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值