React 父子组件、兄弟组件、叔侄应该如何进行通讯,这里描述一下两种方法。
props function
缺点:
消息 订阅与发布
优点:
原理:
找到父子、兄弟、叔侄组件的共同组件,绑定props function,进行通讯。
// 父组件 App.jsx
import React, { Component } from "react";
import List from "./compoments/List";
import Search from "./compoments/Search";
export default class App extends Component {
state = { datas: [] };
dataChange = (data) => {
let { datas } = this.state;
datas.push(data);
this.setState({ datas: datas });
};
render() {
return (
<div>
<Search dataChange={this.dataChange} />
<List datas={this.state.datas} />
</div>
);
}
}
// 子组件 List.jsx
import React, { Component } from "react";
export default class List extends Component {
render() {
return (
<div>
{this.props.datas.map((data) => {
return <div key={data.id}>{data.name}</div>;
})}
</div>
);
}
}
// 子组件 Search.jsx
import React, { Component } from "react";
export default class Search extends Component {
dataChange = () => {
this.props.dataChange({ id: Date.now(), name: "加了加了" });
};
render() {
return (
<div>
<button onClick={this.dataChange}>点击添加一条数据</button>
</div>
);
}
}
// 父组件 App.jsx
import React, { Component } from "react";
import List from "./compoments/List";
import Search from "./compoments/Search";
export default class App extends Component {
state = { datas: [] };
dataChange = (data) => {
let { datas } = this.state;
datas.push(data);
this.setState({ datas: datas });
};
render() {
return (
<div>
<Search dataChange={this.dataChange} />
<List datas={this.state.datas} />
</div>
);
}
}
// 子组件 List.jsx
import React from "react";
export default function List(props) {
return (
<div>
{props.datas.map((data) => {
return <div key={data.id}>{data.name}</div>;
})}
</div>
);
}
// 子组件 Search.jsx
import React from "react";
export default function Search(props) {
let dataChange = () => {
props.dataChange({ id: Date.now(), name: "加了加了" });
};
return (
<div>
<button onClick={dataChange}>点击添加一条数据</button>
</div>
);
}
通过function dataChange进行通信。 操作繁琐,本应跟App.jsx无关的操作,现在代码放到了App.jsx中。
接着使用上面的例子。通过比较可以直接看出优缺点。 不能直接使用,需要安装额外的组件库。这里使用的是PubSubJS,详细内容请查看PubSubJS笔记。
// 父组件 App.jsx
import React, { Component } from 'react';
import List from './compoments/List';
import Search from './compoments/Search';
export default class App extends Component {
render() {
return <div>
<Search />
<List />
</div>
}
}
// 子组件 List.jsx
import React, { Component } from 'react';
import PubSub from 'pubsub-js';
export default class List extends Component {
state={datas:[]}
//组件挂载完毕的钩子
componentDidMount(){
this.dataChangeToken = PubSub.subscribe("dataChange", (msg, data) => {
let { datas } = this.state;
datas.push(data);
this.setState({ datas: datas });
});
}
//组件将要卸载的钩子
componentWillUnmount(){
PubSub.unsubscribe(this.dataChangeToken);
}
render() {
return <div>
{
this.state.datas.map(data=>{
return <div key={data.id}>{data.name}</div>
})
}
</div>
}
}
// 子组件 Search.jsx
import React, { Component } from 'react';
import PubSub from 'pubsub-js';
export default class Search extends Component {
dataChange=()=>{
// 发布消息
PubSub.publish("dataChange", { id: Date.now(), name: "加了加了" });
}
render() {
return <div>
<button onClick={this.dataChange}>我点</button>
</div>
}
}
redux TODO: 有机会整理
TODO: 有机会整理