# React组件沟通
React 是以组合组件的形式组织的,组件因为彼此是相互独立的,从传递信息的内容上看,几乎所有类型的信息都可以实现传递,例如字符串、数组、对象、方法或自定义组件等。所以,在嵌套关系上,就会有两种不同的可能性:父组件向子组件通信、子组件向父组件通信、兄弟组件通信。
# 父子组件沟通
这种方式是最常见的,也是最简单的。
# 父组件更新组件状态
父组件更新子组件状态,通过传递props,就可以了。
class ColorCard extends React.Component {
constructor(props) {
super(props);
this.state = {
color: '#009494'
}
}
render() {
var colorStyle = {
height: 200,
width: 150,
padding: 0,
backgroundColor: "#FFF",
WebkitFilter: "drop-shadow(0px 0px 5px #666)",
filter: "drop-shadow(0px 0px 5px #666)"
}
return ( < div style = {
colorStyle
} >
<
Color color = {
this.state.color
}
/> <
Label color = {
this.state.color
}
/> < /
div > );
}
componentDidMount() {
var that = this;
setTimeout(function() {
that.setState({
color: '#ff0033'
})
}, 10000)
}
}
class Color extends React.Component {
render() {
var colorStyle = {
height: '150px',
width: '150px',
backgroundColor: this.props.color
}
return <div style = {
colorStyle
} > < /div>
}
}
class Label extends React.Component {
render() {
var labelStyle = {
fontFamily: "sans-serif",
fontWeight: "bold",
padding: 13,
margin: 0
};
return <div style = {
labelStyle
} > {
this.props.color
} < /div>
}
}
ReactDOM.render( < ColorCard / > , document.querySelector('#box'));
# 子组件更新父组件状态
这种情况需要父组件传递回调函数给子组件,子组件调用触发即可。
class Child extends React.Component {
handleClick() {
this.props.handleChangeName(this.refs.text.value);
}
render() {
return ( < div >
<
input type = 'text'
ref = "text" / >
<
button onClick = {
this.handleClick.bind(this)
} > 提交 < /button> < /
div > );
}
}
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
text: 'everyone'
}
}
handleChangeName(name) {
this.setState({
text: name
})
}
render() {
return ( < div >
<
p > hello, {
this.state.text
} < /p> <
Child handleChangeName = {
this.handleChangeName.bind(this)
}
/> < /
div > )
}
}
ReactDOM.render( < Parent / > , document.querySelector('#box'));
# 兄弟组件沟通
当两个组件有相同的父组件时,就称为兄弟组件。按照React单向数据流方式,我们需要借助父组件进行传递,通过父组件回调函数改变兄弟组件的props。
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
text: ''
}
}
changeText() {
this.setState({
text: '兄弟组件修改成功'
})
}
render() {
return ( < div >
<
Brother1 changeText = {
this.changeText.bind(this)
}
/> <
Brother2 text = {
this.state.text
}
/> < /
div > )
}
}
class Brother1 extends React.Component {
render() {
return <button onClick = {
this.props.changeText
} > 修改兄弟节点 < /button>
}
}
class Brother2 extends React.Component {
render() {
return <button > {
this.props.text || '未修改'
} < /button>
}
}
ReactDOM.render( < Parent / > , document.querySelector('#box'))
# 组件间的关系:
- 父子组件
- 兄弟组件(非嵌套组件)
- 祖孙组件(跨级组件)
# 几种通信方式:
1.props:
(1).children props
(2).render props
2.消息订阅-发布:
pubs-sub、event等等
3.集中式管理:
redux、dva等等
4.conText:
生产者-消费者模式
# 比较好的搭配方式:
父子组件:props
兄弟组件:消息订阅-发布、集中式管理
祖孙组件(跨级组件):消息订阅-发布、集中式管理、conText(开发用的少,封装插件用的多)
# 消息订阅-发布 (类似于vue $emit)
// npm 安装pubsub-js
// npm install 'pubsub-js'--save
import PubSub from 'pubsub-js' //引入
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
text: ''
}
}
changeText() {
this.setState({
text: '兄弟组件修改成功'
})
}
render() {
return
(
<div>
< Brother1 />
<Brother2 />
</div>
)
}
}
class Brother1 extends React.Component {
changeText=()=>{
let data={}
PubSub.publish('update', data) //发布消息
}
render() {
return <button onClick = {
this.changeText
} > 修改兄弟节点 < /button>
}
}
class Brother2 extends React.Component {
state={
}
componentDidMount(){
this.token=PubSub.subscribe('update', function(data){ //订阅消息
console.log(data)
}); //订阅
}
componentWillUnmount(){
PushSub.unsubscribe(this.token)
}
render() {
return <button > {
this.props.text || '未修改'
} < /button>
}
}
ReactDOM.render( < Parent / > , document.querySelector('#box'))