如果文中有出现纰漏、错误之处,还请大神您多指教。 本文将通过实例的方式记录一下 React 中组件之间的通信方式。
在 React中,需要组件通信的情况一般有以下几种:
父组件向子组件通信 子组件向父组件通信 跨级组件通信 没有嵌套关系组件之间的通信
React数据流动是单向的,父组件向子组件通信也是最常见的。父组件通过 props 向子组件传递需要的信息。 1. 父组件向子组件通信
父组件
import React from 'react'
import TextItem from "../components/TextItem/TextItem"
class Page extends React.Component {
render() {
return (
<div>Hello , <TextItem text='小忆技术体验设计团队'/></div>
);
}
}
export default Page
子组件
import React from 'react'
class TextItem extends React.Component {
render() {
const {text} = this.props
return (
<p>{text}</p>
);
}
}
export default TextItem
2. 子组件向父组件通信
利用回调函数、自定义事件机制
父组件
import React from 'react'
import TextItem from "../components/TextItem/TextItem";
class Page extends React.Component {
handleClick() {
console.log('小忆技术体验设计团队')
}
render() {
return (
<div>Hello , <TextItem text='小忆技术体验设计团队' onClick={() => this.handleClick()}/></div>
);
}
}
export default Page
子组件
import React from 'react'
class TextItem extends React.Component {
render() {
const {text, onClick} = this.props
return (
<p onClick={onClick ? onClick : null}>{text}</p>
);
}
}
export default TextItem
3. 跨级组件通信
层层组件传递 props 例如A组件和B组件之间要进行通信,先找到A和B公共的父组件,A先向C组件通信,C组件通过 props 和B组件通信,此时C组件起的就是中间件的作用。 举个栗子,上代码。
A 组件
import React from 'react'
class A extends React.PureComponent {
state = {
a:'我是 A 里传过来的内容'
}
handleClick() {
const {a} = this.state
const {onClick} = this.props
onClick ? onClick(a) : null
}
render() {
return (
<div onClick={()=>this.handleClick()}>我是A:点我把内容传给B</div>
);
}
}
export default A
B 组件
import React from 'react'
class B extends React.PureComponent {
render() {
const {txt} = this.props
return (
<div>我是B:{txt}</div>
);
}
}
export default B
C 组件
import React from 'react'
import A from "./A";
import B from "./B";
class C extends React.PureComponent {
state = {
str: ''
}
handleClick(txt) {
this.setState({
str: txt
})
}
render() {
return (
<div>
<A onClick={t => this.handleClick(t)}/>
<B txt={this.state.str}/>
</div>
);
}
}
export default C
使用context
在React中子组件跨级访问时,我们可以通过层层传递的方法,但是这样代码不优雅而且当代码多的情况下有些冗余。这时我们可以通过context实现跨级父子组件间的通信。
import React from 'react'
const TextContext = React.createContext('text')
class C extends React.PureComponent {
render() {
return (
<TextContext.Provider value="小忆技术体验设计团队">
<D/>
</TextContext.Provider>
)
}
}
class D extends React.PureComponent {
render() {
return (
<div><E/></div>
)
}
}
class E extends React.PureComponent {
static contextType = TextContext;
render() {
return (
<div>{this.context}</div>
)
}
}
export default C
4. 没有嵌套关系的组件通信
使用自定义事件机制 举个栗子,page2 要去改 page1 的文字,上代码。 先在项目中安装 events
npm i -D events
在 src 下新建一个 utils 目录,里面建一个 events.js
import { EventEmitter } from 'events';
export default new EventEmitter();
Page1
import React, { Component } from 'react';
import emitter from '../utils/events';
class Page1 extends Component {
constructor(props) {
super(props);
this.state = {
message: 'Page1',
};
}
componentDidMount() {
// 组件装载完成以后声明一个自定义事件
this.eventEmitter = emitter.addListener('changeMessage', (message) => {
this.setState({
message,
});
});
}
componentWillUnmount() {
emitter.removeListener(this.eventEmitter);
}
render() {
return (
<div>
{this.state.message}
</div>
);
}
}
export default Page1;
Page2
import React, {Component} from 'react';
import emitter from '../utils/events';
class Page2 extends Component {
handleClick = (message) => {
emitter.emit('changeMessage', message);
};
render() {
return (
<div>
<button onClick={() => this.handleClick('Page2')}>点击我改变Page1组件中显示信息</button>
</div>
);
}
}
export default Page2
