8种方式实现react组件通信

17 篇文章 1 订阅
一:父子传值 (props传值)
  • Child.js
 import React from 'react'
export default function Child({userInfo}) {
  return (
    <div>
      <h1>Child组件</h1>
      <div>
        姓名 ---- {userInfo.name}
        年龄 ---- {userInfo.age}
        性别 ---- {userInfo.gender}
      </div>
    </div>
  )
}
  • Parent.js
import React, { Component } from 'react'
import Child from './Child'
export default class Parents extends Component {
  constructor() {
    super()
    this.state = {
      obj: {
        name: '张三',
        age: 20,
        gender: '男'
      }
    }
  }
  render() {
    let { obj } = this.state;
    return (
      <div>
        <h1>Parent组件</h1>
        <Child userInfo={obj}></Child>
      </div>
    )
  }
}

二:效果如下

image.png

子父传值(props传递函数)
  • Child.js
import React from 'react'

export default function Child({userInfo,setUserInfo}) {

  return (
    <div>
      <h1>Child组件</h1>
      <div>
        姓名 ---- {userInfo.name}
      </div>
      <button onClick={() => setUserInfo("李四")}>设置父组件的用户信息</button>
    </div>
  )
}

  • Parent.js
import React, { Component } from 'react'
import Child from './Child'
export default class Parents extends Component {
  constructor() {
    super()
    this.state = {
      obj: {
        name: '张三',
        age: 20,
        gender: '男'
      }
    }
  }
  getUserInfo = (name)=> {
    let obj = {...this.state.obj}
    obj.name = name;
    this.setState({ obj })
  }
  render() {
    let { obj } = this.state;
    return (
      <div>
        <h1>Parent组件</h1>
        <Child userInfo={obj} setUserInfo={this.getUserInfo}></Child>
      </div>
    )
  }
}

效果图如下

image.png
image.png

三:跨级组件传值 context 相当于vue中的provide和Inject
  • 新建context.js
 import { createContext } from 'react'
export const context = createContext()
  • 新建 GrandFather.js
import React, { Component } from 'react'
import Parents from './Parents'
import { context } from './context'
export default class GrandFather extends Component {
  constructor() {
    super()
    this.state = {
      obj: {
        name: '张爷爷',
        age: '60',
        gender: '男'
      }
    }
  }
  render() {
    return (
      <div>
        <h1>GrandFather组件</h1>
        <context.Provider value={this.state.obj}>
          <Parents></Parents>
        </context.Provider>
      </div>
    )
  }
}

  • Child.js
// import React,{ useContext } from 'react'
import React from 'react'
import { context } from './context'
export default function Child() { // 函数组件使用useContext()
  // const userInfo = useContext(context) // 第一种方式
  return ( 
    <div>
      <h1>Child组件</h1>
       {/* <div>
         姓名: {userInfo.name}---
         年龄: {userInfo.age}---
         性别: {userInfo.gender}
       </div> */}
       {/* 第二种使用消费者模式,不推荐 */}
       <context.Consumer>
        {
          userInfo => {
            return (
              <div>
                姓名: {userInfo.name}---
                年龄: {userInfo.age}---
                性别: {userInfo.gender}
              </div>
            )
          }
        }
       </context.Consumer>
    </div>
  )
}

  • Father.js
import React, { Component } from 'react'
import Child from './Child'
import { context } from './context'
export default class Parents extends Component {
  // static contextType = context // 第一种方式
  constructor() {
    super()
    this.state = {
      obj: {
        name: '张爸爸',
        age: 40,
        gender: '男'
      }
    }
  }
  render() {
    return (
      <div>
        <h1>Parent组件</h1>
        <div>
         姓名: {this.context.name}---
         年龄: {this.context.age}---
         性别: {this.context.gender}
       </div>
        <br/>
        <Child></Child>
      </div>
    )
  }
}
Parents.contextType = context // 第二种方式注入到组件的实例上
效果图如下

image.png

四:全局组件传值之 Nodejs中的events(发布订阅模式)
  • 新建 bus.js
 import { EventEmitter } from 'events'
 export const bus = new EventEmitter() // 导出bus实例
  • 新建child.js
import React from 'react'
import { bus as $bus } from './bus'
export default function Child() { // 函数组件使用useContext()
  const sendMessage = ()=> {
    console.log("触发");
    let obj = {
      name: '张孙子',
      age: 20,
      gender:'男'
    }
    $bus.emit("getMessage",obj)
  }
  return ( 
    <div>
      <h1>Child组件</h1>
      <button onClick={ sendMessage }>发送消息给爷爷组件</button>
    </div>
  )
}

  • 新建 GrandFather.js
import React, { Component } from 'react'
import Parents from './Parents'
import { bus as $bus } from './bus'
export default class GrandFather extends Component {
  constructor() {
    super()
    this.state = {
      obj: {
        name: '张爷爷',
        age: '60',
        gender: '男'
      }
    }
  }
  componentDidMount() {
    this.destory = $bus.addListener("getMessage",(res) => {
      console.log("obj",res);
      this.setState({
        obj: res
      })
    })
  }
  componentWillUnmount() {
    $bus.removeListener(this.destory);
  }
  render() {
    let { name, age, gender } = this.state.obj
    return (
      <div>
        <h1>GrandFather组件</h1>
        <div>
          姓名: {name}----
          年龄: {age} ----
          性别: {gender}
        </div>
        <Parents></Parents>
      </div>
    )
  }
}

五:全局组件传值之 Pubsub.js(发布订阅模式)
 发送消息:PubSub.publish(名称,参数)
 订阅消息:PubSub.subscrib(名称,函数)
 取消订阅:PubSub.unsubscrib(名称)
 yarn add pubsub-js
  • Child.js
import React from 'react'

import PubSub from 'pubsub-js';

export default function Child() { // 函数组件使用useContext()
  const sendMessage = ()=> {
    console.log("触发");
    let obj = {
      name: '张孙子',
      age: 20,
      gender:'男'
    }
    PubSub.publish("getMessage",obj)
  }
  return ( 
    <div>
      <h1>Child组件</h1>
      <button onClick={ sendMessage }>发送消息给爷爷组件</button>
    </div>
  )
}

  • GrandFather.js
import React, { Component } from 'react'
import Parents from './Parents'

import PubSub from 'pubsub-js';
export default class GrandFather extends Component {
  constructor() {
    super()
    this.state = {
      obj: {
        name: '张爷爷',
        age: '60',
        gender: '男'
      }
    }
  }
  componentDidMount() {
    this.destory = PubSub.subscribe("getMessage",(name,res) => { // 第二个参数函数里边的第一个是事件名 第二个参数才是真正的值
      console.log("obj",res);
      this.setState({
        obj: res
      })
    })
  }
  componentWillUnmount() {
    PubSub.unsubscribe(this.destory);
  }
  render() {
    let { name, age, gender } = this.state.obj
    return (
      <div>
        <h1>GrandFather组件</h1>
        <div>
          姓名: {name}----
          年龄: {age} ----
          性别: {gender}
        </div>
        <Parents></Parents>
      </div>
    )
  }
}

效果图如下

image.png

六 ref
  • Parenrts.js
import React, { Component } from 'react';

class Sub extends Component {
  callback() {
    return console.log('执行回调');
  }
  render() {
    return <div>子组件</div>;
  }
}

export default class Parents extends Component {
  constructor(props) {
    super(props);
    this.sub = React.createRef();
  }
  handleOnClick() {
    console.log("this.sub",this.sub.current.callback());
  }
  render() {
    return (
      <div>
        <h1>Fathers组件</h1>
         <button onClick={this.handleOnClick.bind(this)}>获取子组件的方法</button>
        <Sub ref={this.sub}></Sub>
      </div>
    );
  }
}
效果图如下:

image.png

七: redux这里我就不一一写了,前面写过这个redux,
一般我们dispatch触发一个action名字,然后交给reducer纯函数去处理action名字,并且返回一个新的state给store,在每次派发前,都需要通过 store.subscribe订阅监听store中的state,用户通过 store.getState().获取信息展示在页面上

八: 本地缓存 localStorage或者sessionStorage
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lxslxskxs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值