![c78919c659a3fad71cf593740d445ab8.png](https://img-blog.csdnimg.cn/img_convert/c78919c659a3fad71cf593740d445ab8.png)
最近做了一个小项目的迭代。这个项目前端是用React,只是个小型项目所以并没有使用Redux等状态管理的库。刚好遇到了一个小问题:两个不太相关的组件到底该怎么进行通信。
我觉得这个问题还挺有趣的,所以把我的思考过程写下来,大家也可以一起讨论讨论。
虽然重点是要讲两个不相关的组件间的通信,但我还是从最常见的父子组件通信讲起,大家就当温故而知新了。先把完整的总结列出来,然后再详细展开。
组件间通信方式总结
- 父组件 => 子组件:
- Props
- Instance Methods
- Callback Functions
- Event Bubbling
- Parent Component
- Context
- Portals
- Global Variables
- Observer Pattern
- Redux等
1、Props
这是最常见的react组件之间传递信息的方法了吧,父组件通过props把数据传给子组件,子组件通过this.props去使用相应的数据。
const Child = ({
name }) => {
<div>{
name}</div>
}
class Parent extends React.Component {
constructor(props) {
super(props)
this.state = {
name: 'zach'
}
}
render() {
return (
<Child name={
this.state.name} />
)
}
}
2、Instance Methods
第二种父组件向子组件传递信息的方式有些同学可能会比较陌生,但这种方式非常有用,请务必掌握。原理就是:父组件可以通过使用refs来直接调用子组件实例的方法,看下面的例子:
class Child extends React.Component {
myFunc() {
return "hello"
}
}
class Parent extends React.Component {
componentDidMount() {
var x = this.foo.myFunc() // x is now 'hello'
}
render() {
return (
<Child
ref={foo => {
this.foo = foo
}}
/>
)
}
}
大致的过程:
- 首先子组件有一个方法myFunc。
- 父组件给子组件传递一个ref属性,并且采用callback-refs的形式。这个callback函数接收react组件实例/原生dom元素作为它的参数。当父组件挂载时,react会去执行这个ref回调函数,并将子组件实例作为参数传给回调函数,然后我们把子组件实例赋值给this.foo。
- 最后我们在父组件当中就可以使用this.foo来调用子组件的方法咯
了解了这个方法的原理后,我们要考虑的问题就是为啥我们要用这种方法,它的使用场景是什么?最常见的一种使用场景:比如子组件是一个modal弹窗组件,子组件里有显示/隐藏这个modal弹窗的各种方法,我们就可以通过使用这个方法,直接在父组件上调用子组件实例的这些方法来操控子组件的显示/隐藏。
这种方法比起你传递一个控制modal显示/隐藏的props给子组件要美观多了。
class Modal extends React.Component {
show = () => {// do something to show the modal}
hide = () => {// do something to hide the modal}
render() {
return <div>I'm a modal</div>
}
}
class Parent extends React.Component {
componentDidMount() {
if(// some condition) {
this.modal.show()
}
}
render() {
return (
<Modal
ref&#