刚入门 React 可能会因为 React 的单向数据流的特性而遇到组件间沟通的麻烦,这篇文章主要就说一说如何解决组件间沟通的问题。
1. 组件间的关系
1.1 父子组件
ReactJS 中数据的流动是单向的,父组件的数据可以通过设置子组件的 props 传递数据给子组件。如果想让子组件改变父组件的数据,可以在父组件中传一个 callback(回调函数) 给子组件,子组件内调用这个 callback 即可改变父组件的数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
var MyContainer = React.createClass({ getInitialState: function(){ return { list: ['item1', 'item2'], curItem: 'item1' } }, // 改变curItem的回调函数 changeItem: function(item){ this.setState({ curItem: item }); }, render: function(){ return ( <div> The curItem is: {this.state.curItem} <List list={this.state.list} changeItem={this.changeItem}/> </div> ) } }); var List = React.createClass({ onClickItem: function(item){ this.props.changeItem(item); }, render: function(){ return ( <ul> { (function(){ var self = this; return this.props.list.map(function(item){ return ( <li onClick={self.onClickItem.bind(self, item)}>I am {item}, click me!</li> ) }); }.bind(this))() } </ul> ) } }) ReactDOM.render( <MyContainer />, document.getElementById('example') ); |
<MyContainer /> 是<List /> 的父组件,<MyContainer /> 通过 props 传递 list 数据给<List /> 组件,如果<MyContainer /> 中的 list 改变,<List /> 会重新渲染列表数据。而<List /> 可以通过<MyContainer /> 传来的 changeItem 函数,改变<MyContainer /> 的 curItem 数据。
1.2 兄弟组件
当两个组件不是父子关系,但有相同的父组件时,将这两个组件称为兄弟组件。兄弟组件不能直接相互传送数据,此时可以将数据挂载在父组件中,由两个组件共享:如果组件需要数据渲染,则由父组件通过 props 传递给该组件;如果组件需要改变数据,则父组件传递一个改变数据的回调函数给该组件,并在对应事件中调用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
var MyContainer = React.createClass({ getInitialState: function(){ return { list: ['item1', 'item2'], curItem: 'item1' } }, // 改变curItem的回调函数 changeItem: function(item){ this.setState({ curItem: item }); }, render: function(){ return ( <div< |