react基础组件几种通信方法

react基础组件几种通信方法

1.父子组件通信
父组件向子组件通信:使用 props
子组件向父组件通信:使用 props 回调

本文使用React 16.8 的新增特性 Hook示例

 // Parents父组件 
 // 使用 props val 传值
 // 通过 emit自定义事件 childChange 接收子组件回调
 import React, { useState } from 'react';
import ChildrenA from './ChildrenA';
function Parents(props) {
    const [val, setVal] = useState('john')
    const handleChange = (v) => { setVal(v) }
    return (
        <div>
            这是ChildrenA emit的值:{val}
            <ChildrenA val={val} childChange = { handleChange}></ChildrenA>
        </div>
    )
}
export default  Parents

 // ChildrenA子组件 
 // 通过 props.val 接收父组件传值
 // 通过 emit自定义事件 props.childChange 传递给父组件
import React, { useState } from 'react';
function ChildrenA(props) {
   const [val, setVal] = useState(props.val)
    const changeVal = (e) =>{
        setVal(e.target.value)
        props.childChange(e.target.value)
    }
    return (
        <div>
            这是Parents props传递的值:{val}
            <input type="text" value={val} onChange={changeVal}/>
        </div>
    )
}
export default ChildrenA
2.跨级组件间通信:

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

2.1中间组件层层传递 props(多层嵌套不建议)
2.2使用 context 对象

App 组件,这里作为爷组件

import React from 'react';
import PropTypes from "prop-types";
import Parents from './views/main/Parents';
class App extends React.Component {
    // 父组件声明自己支持 context
    constructor() {
        super();
        this.state = {
            msg: ''
        }
    }
    static childContextTypes = {
        color: PropTypes.string,
        callback: PropTypes.func,
    }
    // 父组件提供一个函数,用来返回相应的 context 对象
    getChildContext(){
        return {
            color: "red",
            callback: this.callback.bind(this)
        }
    }
    callback(val){
        this.setState({msg: val})
        console.log(val)
    }
    render() {
        return (
            <div className="App">
                子集传值:{this.state.msg}
                <Parents></Parents>
            </div>
        );
    }
}
export 

Parents 这里做子组件,可以理解为中间很多层

import React from 'react';
import ChildrenA from './ChildrenA';
function Parents() {
    return (
        <>
            <ChildrenA/>
        </>
    )
}
export default  Parents

ChildrenA 孙组件,可以理解为多层嵌套

import React from 'react';
import PropTypes from "prop-types";

class ChildrenA extends React.Component {
    // 子组件声明自己需要使用 context
    static contextTypes = {
        color:PropTypes.string,
        callback:PropTypes.func,
    }
    cb (msg){
        return () => {
            this.context.callback(msg);
        }
    }
    render() {
        return (
            <div style={{ color:this.context.color }}>
                {this.context.color}
                <button onClick = { this.cb("john!") }>点击我</button>
            </div>
        )
    }
}
export default ChildrenA

3.非嵌套组件间通信:
3.1利用二者共同父组件的 context 对象进行通信
3.2使用自定义事件的方式(使用 events 包)

安装依赖包

npm install events --save

新建一个 ev.js,引入 events 包,并向外提供一个事件对象,供通信时使用:

import { EventEmitter } from "events";
export default new EventEmitter();

父级

import React from 'react';
import ChildrenA from './ChildrenA';
import ChildrenB from './ChildrenB';
function Parents() {
    return (
        <>
            <ChildrenA/>
            <ChildrenB/>
        </>
    )
}
export default  Parents

子级A

import React from "react";
import emitter from "./ev"

export default class ChildrenA extends React.Component{
    constructor(props) {
        super(props);
        this.state = {
            msg:null,
        };
    }
    componentDidMount(){
        // 声明一个自定义事件
        // 在组件装载完成以后
        this.eventEmitter = emitter.addListener("callMe",(msg)=>{
            this.setState({
                msg
            })
        });
    }
    // 组件销毁前移除事件监听
    componentWillUnmount(){
        emitter.removeListener(this.eventEmitter);
    }
    render(){
        return(
            <div>
                我是非嵌套 ChildrenA
                <p>这是ChildrenB传的值:{ this.state.msg }</p>
            </div>
        );
    }
}

子级B

import React from "react";
import emitter from "./ev"

export default class ChildrenB extends React.Component{
    render(){
        const cb = (msg) => {
            return () => {
                // 触发自定义事件
                emitter.emit("callMe","Hello,john")
            }
        }
        return(
            <div>
                我是非嵌套 ChildrenB
                <button onClick = { cb("blue") }>点击我</button>
            </div>
        );
    }
}

4.状态管理通信:
Redux 、MobX 、dvajs 等状态管理,这里不做介绍

这是一篇沉没于知识大海的博客; 每天进步一点点,记录成长点滴。–john

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值