處理 React 組件之間的交流方式,主要取決于組件之間的關系,然而這些關系的約定人就是你。
React 組件之間交流的方式,可以分為以下 3 種:
- [父組件] 向 [子組件] 傳值(Parent 與 Child_1、Child_2、Child_1_1、Child_1_2、Child_2_1);
- [子組件] 向 [父組件] 傳值(Child_1與Parent);
- 兄弟組件之間傳值(Child_1 與 Child_2、Child_1_1 與 Child_2、etc.)
組件之間關系
1.[父組件] 向 [子組件] 傳值
通訊是單向的,數據必須是由一方傳到另一方。在 React 中,父組件可以向子組件通過傳 props 的方式,向子組件進行通訊。
var MyContainer = React.createClass({
getInitialState:()=>{
return {
checked:true
}
},
render(){
return <ToggleButton text="Toggle me" checked={this.state.checked} />
}
})
var ToggleButton = React.createClass({
render(){
return <div>
<label>{this.props.text}:<input type="checkbox" checked={this.props.checked}/></label>
</div>
}
})
如果父組件與子組件之間不止一個層級,如 Parent 與 Child_1_1 這樣的關系,可通過 ... 運算符(Object 剩余和展開屬性),將父組件的信息,以更簡潔的方式傳遞給更深層級的子組件。
var MyContainer = React.createClass({
getInitialState:()=>{
return {
checked:true
}
},
render(){
return <ToggleButton text="Toggle me" checked={this.state.checked} />
}
})
var ToggleButton = React.createClass({
render(){
return <div>
<label>{this.props.text}:<input type="checkbox" checked={this.props.checked}/></label>
<Child {...this.props}/>
</div>
}
});
var Child = React.createClass({
render(){
return <p>{this.props.text}</p>
}
})
2.[子組件] 向 [父組件] 傳值
在上一個例子中,父組件可以通過傳遞 props 的方式,自頂而下向子組件進行通訊。而子組件向父組件通訊,同樣也需要父組件向子組件傳遞 props 進行通訊,只是父組件傳遞的,是作用域為父組件自身的函數,子組件調用該函數,將子組件想要傳遞的信息,作為參數,傳遞到父組件的作用域中。
var MyContainer = React.createClass({
getInitialState:()=>{
return {
checked:false
}
},
onChildChange(newState){
this.setState({checked:newState})
},
render(){
var isChecked = this.state.checked ? 'yes' : 'no'
return <div>
<h4>Are yao checked:{isChecked}</h4>
<ToggleButton text="Toggle me" initialChecked={this.state.checked} callbackParent={this.onChildChange}/>
</div>
}
})
var ToggleButton = React.createClass({
getInitialState(){
return {
checked:this.props.initialChecked
}
},
onTextChange(){
var newState = !this.state.checked;
this.setState({checked:newState});
this.props.callbackParent(newState);
},
render(){
return <div>
<label>{this.props.text}:<input type="checkbox" checked={this.state.checked} onChange={this.onTextChange}/></label>
</div>
}
});
可以用如下的流程圖和形象的描述上述的傳遞過程:
3.兄弟組件之間傳值
對于沒有直接關聯關系的兩個節點,就如 Child_1 與 Child_2 之間的關系,他們唯一的關聯點,就是擁有相同的父組件。如果我們由 Child_1 向 Child_2 進行通訊,我們可以先通過 Child_1 向 Parent 組件進行通訊,再由 Parent 向 Child_2 組件進行通訊,所以有以下代碼。
var Parent = React.createClass({
getInitialState(){
return {
msg:"start"
}
},
transferMsg(msg){
this.setState({msg:msg})
},
render(){
return <div>
<Child_1 transferMsg={msg=>this.transferMsg(msg)}/>
<Child_2 msg={this.state.msg}/>
</div>
}
})
var Child_1 = React.createClass({
componentDidMount() {
setTimeout(() => {
this.props.transferMsg('end')
}, 1000);
},
render() {
return <div>
<p>child_1 component</p>
</div>
}
})
var Child_2 = React.createClass({
render() {
return <div>
<p>child_2 component: {this.props.msg}</p>
</div>
}
})
所有DEMO的地址:https://github.com/react-redux-demo/react-component-communication