这两天被长期抽调到别的项目组去做一个小我的项目的迭代。这个我的项目前端是用 React,只是个小型我的项目所以并没有应用 Redux 等状态治理的库。刚好遇到了一个小问题:两个不太相干的组件到底该怎么进行通信。我感觉这个问题还挺乏味的,所以把我的思考过程写下来,大家也能够一起探讨探讨。
尽管重点是要讲两个不相干的组件间的通信,但我还是从最常见的父子组件通信讲起,大家就当温故而知新了。先把残缺的总结列出来,而后再具体开展。
组件间通信形式总结
-
父组件 => 子组件:
- Props
- Instance Methods
-
子组件 => 父组件:
- Callback Functions
- Event Bubbling
-
兄弟组件之间:
- Parent Component
-
不太相干的组件之间:
- Context
- Portals
- Global Variables
- Event Bus
- Redux/Flux
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={el => {this.modal = el}}
/>
)
}
}
3. Callback Functions
讲完了父组件给子组件传递信息的两种形式,咱们再来讲子组件给父组件传递信息的办法。回调函数这个办法也是 react 最常见的一种形式,子组件通过调用父组件传来的回调函数,从而将数据传给父组件。
const Child = ({onClick}) => {<div onClick={() => onClick('zach')}>Click Me</div>
}
class Parent extends React.Component {handleClick = (data) => {console.log("Parent received value from child:" + data)
}
render() {
return (<Child onClick={this.handleClick} />
)
}
}
4. Event Bubbling
这种办法其实跟 react 自身没有关系,咱们利用的是原生 dom 元素的事件冒泡机制。
class Parent extends React.Component {render() {
return (<div onClick={this.handleClick}>
<Child />
</div>
);
}
handleClick = () => {console.log('clicked')
}
}
function Child {
return (<button>Click</button>);
}
奇妙的利用下事件冒泡机制,咱们就能够很不便的在父组件的元素上接管到来自子组件元素的点击事件
5. Parent Component
6. Context
7. Portals
8. Global Variables
9. Event Bus
10. Redux/Flux
先公布下,今天持续更新