上一篇文章咱们经过一个ToDoList案例,系统的讲解了React父子组件之间的通讯。本篇文章咱们依然经过一个实用的案例来为你们讲解React兄弟组件之间的通讯。javascript
React项目中的两个兄弟组件若要传递数据,则首先须要先将数据从一个兄弟组件传递给他们的公共父组件,而后再由这个公共父组件将数据传递给另外一个兄弟组件。数据传递的原理以下图所示。
咱们经过一个案例来讲明兄弟组件之间的通讯方式。该案例是一个颜色调色板,页面中有三个滑竿,分别能够调整红色、绿色、蓝色的取值范围(0-255),在调整任意滑竿的过程当中,会自动显示最终生成的颜色代码,并将具体的颜色展现在一个div容器中。案例效果图以下图所示。前端
该案例为了实现兄弟组件之间的数据传递,咱们将其划分为三个组件。java
本案例中,三个滑竿的取值决定了最终的颜色代码和颜色展现。因此初始化的数据位于组件ColorSelector中,当滑竿发生变化时,三个滑竿的取值都要传递给父组件,父组件将其转换为颜色代码,再传递给子组件ColorBoard,子组件将其做用在用于展现颜色的div的背景颜色属性上。组件之间数据的传递方向以下图所示。小程序
咱们将组件划分好以后,先按照效果图将各个组件的元素位置书写好。微信小程序
class ColorSelector extends Component{ constructor(props){ super(props); this.state={ colors:[255,255,255] } } render(){ return ( <Fragment> { this.state.colors.map((item,index)=>{ return <input type="range" key={index} min={0} max={255} /> }) } </Fragment> ) } }
为了可以获取三个滑竿的最终数值,咱们在state区设置了一个名为colors的数据,该数据是一个数组,共有三个数组元素,分别用来表示三个滑竿的最终数值。数组
滑竿也属于表单元数,和上一篇文章中使用文本框的方法是同样的。为滑竿添加value属性设置默认值,绑定onChange事件获取用户交互数据,在onChange事件中使用event.target.value获得最终的结果。因此上述代码中滑竿的部分最终变为下列格式。微信
return <input type="range" key={index} min={0} max={255} value={item} onChange={()=>this.colorChange(event,index)} />
class ColorBoard extends Component{ render(){ return ( <Fragment> <div className="board"></div> </Fragment> ) } }
ColorBoard组件只具有一个div容器,最终会接收父组件Color传递过来的颜色代码并经过style属性改变背景颜色。app
class Color extends Component{ constructor(props) { super(props); this.state={ color:'#FFFFFF' } } render(){ return ( <Fragment> <ColorBoard /> <div>颜色代码:{this.state.color}</div> <ColorSelector /> </Fragment> ) } }
父组件为了接受子组件ColorSelector传递过来的数组并最终转换为颜色代码,在其state区设置了一个名为color的数据。函数
因为滑竿在子组件ColorSelector中,因此咱们要先进行子组件向父组件的数据传递。这时父组件要在调用子组件时设置一个自定义事件,并在子组件中滑竿的onChange事件中调用这个自定义事件。this
父组件在调用ColorSelector子组件时设置的自定义事件以下所示。
<ColorSelector onSelect={this.colorSelect.bind(this)}/>
子组件ColorSelector的滑竿onChange事件以下所示。
colorChange(event,index){ const {onSelect}=this.props; let colors=[...this.state.colors]; colors[index]=parseInt(event.target.value); this.setState({ colors }); onSelect(this.state.colors); }
在该段代码中,首先把记录三个滑竿数据的数组colors解构为colors变量,并经过event.target.value获取索引值为index的滑竿的最终数据,经过索引值改变变量colors的数组元素取值,并最终将变量colors再复制给state数据colors。最后调用父组件的onSelect事件,并将state区的colors数组传给父组件的onSelect事件。
父组件中自定义事件onSelect触发时执行的函数以下所示。
colorSelect(colors){ let temp='#' + colors.map(item=>{ return item>15?item.toString(16):'0'+item.toString(16); }).join(''); this.setState({ color:temp.toUpperCase() }) }
父组件的onSelect事件接收到子组件ColorSelector传递的数组,将其遍历并将每一个数组元素转换为16进制,最终变为表示颜色色代码的字符串。最后将这个字符串所有转换为大写,并赋值给父组件state区的color数据,这样既能够用于传递给子组件ColorBoard,也能够用于在页面上显示颜色代码。
接下来,父组件应该将接收到的颜色代码color传递给另外一个子组件ColorBoard了,以用来在div容器中显示背景颜色。这时,父组件在调用子组件ColorBoard时,应该为其设置一个自定义属性,用来传递颜色代码。代码以下所示。
<ColorBoard color={this.state.color}/>
子组件ColorBoard应该获取父组件传递的颜色代码并经过style属性改变div容器的背景颜色。代码以下所示。
const {color}=this.props; return ( <Fragment> <div className="board" style={{backgroundColor:color}}></div> </Fragment> )
至此,三个滑竿的数据完整的从子组件ColorSelector中传递给了另外一个子组件ColorBoard,在父组件中转的过程当中,将ColorSelector传来的数组转换为颜色代码传给ColorBoard。兄弟组件之间地通讯顺利完成。
const {Component,Fragment} = React; /*子组件ColorBoard*/ class ColorBoard extends Component{ render(){ const {color}=this.props; return ( <Fragment> <div className="board" style={{backgroundColor:color}}></div> </Fragment> ) } } /*子组件ColorSelector*/ class ColorSelector extends Component{ constructor(props){ super(props); this.state={ colors:[255,255,255] } } colorChange(event,index){ const {onSelect}=this.props; let colors=[...this.state.colors]; colors[index]=parseInt(event.target.value); this.setState({ colors }); onSelect(this.state.colors); } render(){ return ( <Fragment> { this.state.colors.map((item,index)=>{ return <input type="range" key={index} min={0} max={255} value={item} onChange={()=>this.colorChange(event,index)} /> }) } </Fragment> ) } } /*父组件Color*/ class Color extends Component{ constructor(props) { super(props); this.state={ color:'#FFFFFF' } } colorSelect(colors){ let temp='#' + colors.map(item=>{ return item>15?item.toString(16):'0'+item.toString(16); }).join(''); this.setState({ color:temp.toUpperCase() }) } render(){ return ( <Fragment> <ColorBoard color={this.state.color}/> <div>颜色代码:{this.state.color}</div> <ColorSelector onSelect={this.colorSelect.bind(this)}/> </Fragment> ) } } ReactDOM.render( <Color></Color>, document.getElementById('app') );
本文是React系列教程的第五篇文章,主要为你们讲解了React兄弟组件之间的通讯方式。本质是依然是父子组件之间的通讯。明天会为你们系统的讲解React中受控表单元素的使用方法。
小海前端,具备18年Web项目开发和先后台培训经验,在前端领域著有较为系统的培训教材,对Vue.js、微信小程序开发、uniApp、React等全栈开发领域都有较为深的造诣。入住Segmentfault,但愿可以更多的结识Web开发领域的同仁,将Web开发大力的进行普及。同时也愿意与你们进行深刻的技术研讨和商业合做。