处理组件之间的通信, 主要取决于组件之间的关系,因此我们划分为以下三种:
【父组件】向【子组件】传值;
【子组件】向【父组件】传值;
【组件A】向无关系【组件B】传值,一般为兄弟组件;
一、「父组件」向「子组件」传值
这是最普遍的用法,实现上也非常简单,主要是利用props来实现
// 父组件 import React from 'react'; import Son from './components/son'; class Father extends React.Component { constructor(props) { // 这里要加super,否则会报错 super(props); this.state = { checked: true } } render() { return ( <Son text="Toggle me" checked={this.state.checked} /> ) } }
// 子组件 class Son extends React.Component { render() { // 接收来自父组件的参数 let checked = this.props.checked, text = this.props.text; return ( <label>{text}: <input type="checkbox" checked={checked} /></label> ) } }
多想一点:
如果组件的嵌套层次太多,那么从外到内的交流成本就会加深,通过 props 传值的优势就不明显,因此,我们还是要尽可能的编写结构清晰简单的组件关系, 既也要遵循组件独立原则,又要适当控制页面,不可能或极少可能会被单用的代码片,可不编写成一个子组件
二、「子组件」向「父组件」传值
我们知道,react的数据控制分为两种,为 props 和 state;其中,props 如上刚介绍过,它是父组件向子组件传值时作为保存参数的数据对象;而 state 是组件存放自身数据的数据对象。这两者最主要的区别就是,props属于父组件传给子组件的只读数据,在子组件中不能被修改,而state在自身组件中使用时,可以通过setState来修改更新。
子组件向父组件传值,需要控制自己的state,并发起父组件的事件回调来通知父组件
// 父组件 import Son from './components/son'; class Father extends React.Component { constructor(props) { super(props) this.state = { checked: false } } onChildChanged() { this.setState({ checked: newState }) } render() { let isChecked = this.state.checked ? 'yes' : 'no'; return ( <div> <span>Are you checked: {isChecked }</span> <Son text="Toggle me" initialChecked={this.state.checked} callbackParent={this.onChildChanged.bind(this)} ></Son> </div> ) } }
// 子组件 class Son extends React.Component { constructor(props) { super(props); this.state = { checked: this.props.initialChecked } } onTextChange() { let newState = !this.state.check.checked; this.setState({ checked: newState }); // 注意,setState 是一个异步方法,state值不会立即改变,回调时要传缓存的当前值, // 也可以利用传递一个函数(以上传的是对象),并传递prevState参数来实现数据的同步更新 this.props.callbackParent(newState); } render() { let text= this.props.text; let checked = this.state.checked; return ( <label>{text}: <input type="checkbox" checked={checked} onChange={this.onTextChange.bind(this)}></label> ) } }
多想一点:
同样应当避免深层次的组件嵌套
这里其实是依赖了props来传递事件的引用,并通过回调的方式来实现,在没有使用工具情况下,可以使用该办法
拓展一点:
在onChange 事件或者其他React事件中,你能获取以下信息:
「this」 指向你的组件
「一个参数」 一个react合成事件, SyntheticEvent
我们知道,React对所有事件的管理都是自己封装实现的,html中的 onclick 被封装成了 onClick, onchange 被封装成了 onChange。从根本上来说,他们都是被绑定在body上的。
多个子组件回调同一个回调函数情况
父组件中大概率包含多个子组件,为节省和简洁代码,遵循 don't repeat yourself 原则,我们会让一个回调函数实现多个子组件的功能,或多个组件协作完成指定功能
import React from 'react'; import Son from './components/son'; class Father extends React.Componnet { constructor(props) { super(props); this.state = { totalChecked: 0 } } onChildChangeed() { let newTotal = this.state.totalChecked + (new State ? 1 : -1 ); this.setState({ totalChecked = this.state.totalChecked; }); } render() { return ( <div> <div>Checked numbers: {this.state.totalChecked}</div> <Son text="Toggle me" initialChecked={this.state.checked} callbackParent={this.onChildChanged} /> <Son text="Toggle me too" initialChecked={this.state.checked} callbackParent={this.onChildChanged} /> <Son text="Add me" initialChecked={this.state.checked} callbackParent={this.onChildChanged} /> </div> ) } }