这两天被临时抽调到别的项目组去做一个小项目的迭代。这个项目前端是用React,只是个小型项目所以并没有使用Redux等状态管理的库。刚好遇到了一个小问题:两个不太相关的组件到底该怎么进行通信。我觉得这个问题还挺有趣的,所以把我的思考过程写下来,大家也可以一起讨论讨论。
虽然重点是要讲两个不相关的组件间的通信,但我还是从最常见的父子组件通信讲起,大家就当温故而知新了。先把完整的总结列出来,然后再详细展开。
父组件 => 子组件:
子组件 => 父组件:
兄弟组件之间:
不太相关的组件之间:
这是最常见的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} /> ) } }
第二种父组件向子组件传递信息的方式有些同学可能会比较陌生,但这种方式非常有用,请务必掌握。原理就是:父组件可以通过使用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 }} /> ) } }
大致的过程:
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 }} /> ) } }
讲完了父组件给子组件传递信息的两种方式,我们再来讲子组件给父组件传递信息的方法。回调函数这个方法也是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} /> ) } }
这种方法其实跟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> ); }
巧妙的利用下事件冒泡机制,我们就可以很方便的在父组件的元素上接收到来自子组件元素的点击事件
先发布下,明天继续更新