前言:相信很多用过React或者刚刚开始接触的人,对组件间的通信都深有感触,那么下面就我自己的工作经验给大家说一下,因为父子通信大家都比较熟悉,下面介绍的会着重对没有嵌套关系的组件通信。
一:父传子主要应用props
二:子传父用回调或者自定义事件
三:没有嵌套关系组件通信
我们在处理事件的过程中需要注意,在componentDidMount事件中,如果组件挂载完成,再订阅事件;当组件卸载的时候,在componentEillUnmount事件中取消事件的订阅。
我们常用的发布/订阅模式来举例,这里借用Node.js Events模块的浏览器版实现。
对于React使用场景来说,EventEmitter只需要单例就可以,因此我们需要单独初始化EventEmitter实例(以前在应用兄弟间组件通信都是通过父组件实现的,但是如果这样层级较深,做起来简直是噩梦,所以在这里应用一个方法EventEmitter,相信很多人对此都了解)这里附上自己测试页面:
父页面Test
import List from './List';
import emitter from './events';
class Test extends Component{
constructor(props){
super(props);
this.state = {
value:[{text:1},{text:2}]
}
}
componentDidMount(){
this.itemChange = emitter.addListener('ItemChange',(msg,data) => {
console.log(data,'dddddddd',msg)
})
}
componentWillUnmount(){
emitter.removeListener(this.itemChange);
}
valueChange = value => {
this.setState({
value,
})
}
render(){
return(
<List list={this.state.value}></List>
)
}
}
export default Test
import ListItem from './ListItem';
import emitter from './events';
class List extends Component{
constructor(props){
super(props);
this.state = {
list:this.props.list.map(entry => ({
text:entry.text,
checked:entry.checked || false,
}))
}
}
onItemChange(entry){
const {list} = this.state;
this.setState({
list:list.map(preEntry => ({
text:preEntry.text,
checked:preEntry.text === entry.text ? !preEntry.checked : preEntry.checked,
}))
});
emitter.emit('ItemChange',entry);
}
render(){
return (
<div>
<ul>
{this.state.list.map((entry,index) => {
return (
<ListItem
key={`list-${index}`}
value={entry.text}
checked={entry.checked}
onChange={this.onItemChange.bind(this,entry)}/>
)
})}
</ul>
</div>
)
}
}
export default List
class ListItem extends Component {
static defaultProps = {
checked:false
}
constructor(props){
super(props);
}
render() {
return(
<li>
<input type='checkbox' checked={this.props.checked} onChange={this.props.onChange}/>
<span>{this.props.value}</span>
</li>
);
}
}
export default ListItem
export default new EventEmitter();
现在项目中应用的是antd初始化的项目,所以里面把这些都封装的很好,平常我们应用兄弟通信都是通过dispatch,去改变model中state,比如说,A是父组件有两个子组件B和C,在B中某个事件调用中应用dispatch去改变model中state,C中获取model中改变了的state,就可以达到通信的目的,附带吗;
B中代码:
this.props.dispatch({
type:'acceptLetterInfoList/loadMyMailTableList',
payload:{
props:{
messageFirst:-1,
pageIndex: 1,
pageSize: 20
}
}
});
this.setState({
messageFirst:-1,
});
}} tab={item.tab}>{item.content}</TabPane>
C中从props中获取:
有什么说的不对或者哪里有问题,希望大家贴帖,我们共同讨论