React组件通信
1.父子组件通信
1.1父传子 采用props的格式
父组件 中
export default class Father extends Component {
//数据状态
state = {todos:[
{id:'001',name:'吃饭',done:true},
{id:'002',name:'睡觉',done:true}
]}
render() {
const {todos} = this.state
return (
<div>
// 在父组件里引入的子组件上进行传值
<child todos={todos} />
</div>
)
}
}
子组件 中
export default class List extends Component {
//对接收的props进行:类型、必要性的限制
static propTypes = {
todos:PropTypes.array.isRequired,
}
render() {
// 子组件从this.props中获取父组件传过来的参数
const {todos} = this.props
return (
<ul>
{
todos.map( todo =>{
return <li key={todo.id} >{todo.name}</li>
})
}
</ul>
)
}
}
1.2 子传父
子传父 通过在父组件引入的子组件中通过props传递一个函数并传参,子组件去触发这个函数更改参数完成数据更新
父组件中
export default class Father extends Component {
//数据状态
state = {todos:[
{id:'001',name:'吃饭',done:true},
{id:'002',name:'睡觉',done:true}
]}
deleteTodo(id) => {
//获取原来的todos
const {todos} = this.state
//删除指定id的todo对象
const newTodos = todos.filter((todoObj)=>{
return todoObj.id !== id
})
//更新状态
this.setState({todos:newTodos})
}
render() {
const {todos} = this.state
return (
<div>
// 在父组件里通过props传递函数给子组件
<child
todos={todos}
deleteTodo={this.deleteTodo}/>
</div>
)
}
}
子组件 中
export default class List extends Component {
//对接收的props进行:类型、必要性的限制
static propTypes = {
todos:PropTypes.array.isRequired,
}
handleDelete = (id)=>{
// 触发父组件函数 这个函数是在父组件中props传过来的
this.props.deleteTodo(id)
}
render() {
// 子组件从this.props中获取父组件传过来的参数
const {todos} = this.props
return (
<ul>
{
todos.map( todo =>{
return
<li key={todo.id} >
{todo.name}
<button onClick={()=> this.handleDelete(todo.id) }>删除</button>
</li>
})
}
</ul>
)
}
}
2.兄弟组件通信
介绍一款插件,pubsub 这个可以采用发布订阅的方式实现组件间的传值
- 安装
npm install pubsub-js --save - react 页面引入pubsubjs
import PubSub from ‘pubsub-js’ - pubsubjs使用
发送消息:PubSub.publish(名称,参数)
订阅消息:PubSub.subscrib(名称,函数)
取消订阅:PubSub.unsubscrib(名称)
发布
import React, { Component } from 'react';
import PubSub from 'pubsub-js';
export default class Home extends Component {
constructor(props){
super(props);
this.state={
increase:'increase'
}
}
buttonIncrease(){
PubSub.publish('PubSubmessag',this.state.increase);
}
render() {
return (
<div>
<button onClick={this.buttonIncrease.bind(this)}>点我</button>
</div>
)
}
}
订阅
import React, { Component } from 'react';
import PubSub from 'pubsub-js';
export default class Brother extends Component{
constructor(props){
super(props);
this.state={
increase:'none',
}
}
componentDidMount(){
this.pubsub_token = PubSub.subscribe('PubSubmessage', function (topic,message) {
this.setState({
increase: message
});
}.bind(this));
}
componentWillUnmount(){
PubSub.unsubscribe(this.pubsub_token);
}
}
3.祖孙组件传值
通过生产者-消费者模式 conText
爷爷组件 中
import React, { Component } from "react";
import Father from "./components/Father"; // 引入父组件(爷爷的儿子组件)
import proptypeskey from "prop-types"; // 需要单独下载插件 npm install --save prop-types
export default class Grandpa extends Component {
// 也是人家提供的,不可以改变 传递给孙子组件的类型(必须写)
// 爷爷组件传递给孙子组件,依赖于 prop-types;(验证参数的格式)
static childContextTypes = {
title: proptypeskey.string,
};
// getChildContext是人家提供的,设置穿度的内容(必须写)
getChildContext() {
return {
title: "营业员==>给孙子的"
};
}
render() {
return (
<div>
{/* 父组件传递给子组件的值 */}
<Father ></Father >
</div>
);
}
}
父组件 父组件不需要做任何操作
import React, { Component } from "react";
import SuoZi from "./SuoZi"; // 引入孙子组件 父组件的儿子
export default class Father extends Component {
render() {
return (
<div>
<SuoZi></SuoZi>
</div>
);
}
}
孙组件
import React, { Component } from "react";
// 引入验证格式类型的插件
import proptypeskey from "prop-types";
export default class SuoZi extends Component {
// 也是人家提供的,不可以改变(必须写)
static contextTypes = {
title: proptypeskey.string,
};
render() {
return (
<div>
{/* 获取值 */}
<p>爷爷=={this.context.title} </p>
</div>
);
}
}
另外还有利用redux进行集中式管理从而进行组件通信
函数式组件中父子通信利用react hooks进行通信
以上两种由于内容偏多会在以后文章进行讲解
总结 搭配方式
类式父子组件:props | 函数式父子组件组件:react hooks
兄弟组件:消息订阅-发布(pub-sub)、集中式管理(redux)
祖孙组件:消息订阅-发布(pubs-sub)、集中式管理(redux)、(生产者-消费者模式)conText