React 组件通信方式
react组件间通信常见的几种情况 :
- 父组件向子组件通信
- 子组件向父组件通信
- 跨级组件通信
- 非嵌套关系的组件通信
父组件向子组件通信
父组件通过 props 向子组件传递需要的信息。父传子是在父组件中直接绑定一个正常的属性,这个属性就是指具体的值,在子组件中,用props就可以获取到这个值
1 2 3 4 5 6 7 8 9
| const Child = props =>{ return <p>{props.name}</p> }
const Parent = ()=>{ return <Child name="京程一灯"></Child> }
|
子组件向父组件通信
props + 回调的方式,使用公共组件进行状态提升。子传父是先在父组件上绑定属性设置为一个函数,当子组件需要给父组件传值的时候,则通过props调用该函数将参数传入到该函数当中,此时就可以在父组件中的函数中接收到该参数了,这个参数则为子组件传过来的值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| const Child = props =>{ const cb = msg =>{ return ()=>{ props.callback(msg) } } return ( <button onClick={cb("京程一灯欢迎你!")}>京程一灯欢迎你</button> ) }
class Parent extends Component { callback(msg){ console.log(msg) } render(){ return <Child callback={this.callback.bind(this)}></Child> } }
|
跨级组件通信
父组件向子组件的子组件通信,向更深层子组件通信。
- 使用props,利用中间组件层层传递,但是如果父组件结构较深,那么中间每一层组件都要去传递props,增加了复杂度,并且这些props并不是中间组件自己需要的。
- 使用context,context相当于一个大容器,我们可以把要通信的内容放在这个容器中,这样不管嵌套多深,都可以随意取用,对于跨越多层的全局数据可以使用context实现。
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
|
const BatteryContext = createContext();
class GrandChild extends Component { render(){ return ( <BatteryContext.Consumer> { color => <h1 style={{"color":color}}>我是红色的:{color}</h1> } </BatteryContext.Consumer> ) } }
const Child = () =>{ return ( <GrandChild/> ) }
class Parent extends Component { state = { color:"red" } render(){ const {color} = this.state return ( <BatteryContext.Provider value={color}> <Child></Child> </BatteryContext.Provider> ) } }
|
非嵌套关系的组件通信
即没有任何包含关系的组件,包括兄弟组件以及不在同一个父级中的非兄弟组件。
- 可以使用自定义事件通信(发布订阅模式),使用pubsub-js
- 可以通过redux等进行全局状态管理
- 如果是兄弟组件通信,可以找到这两个兄弟节点共同的父节点, 结合父子间通信方式进行通信
- 也可以new一个 Vue 的 EventBus,进行事件监听,一边执行监听,一边执行新增 VUE的eventBus 就是发布订阅模式,是可以在React中使用的;
setState 既存在异步情况也存在同步情况
异步情况 在React事件当中是异步操作
同步情况 如果是在setTimeout事件或者自定义的dom事件中,都是同步的
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
| import React,{ Component } from "react"; class Count extends Component{ constructor(props){ super(props); this.state = { count:0 } }
render(){ return ( <> <p>count:{this.state.count}</p> <button onClick={this.btnAction}>增加</button> </> ) } btnAction = ()=>{ setTimeout(()=>{ this.setState({ count: this.state.count + 1 }); console.log(this.state.count); }) } }
export default Count;
|
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
| import React,{ Component } from "react"; class Count extends Component{ constructor(props){ super(props); this.state = { count:0 } }
render(){ return ( <> <p>count:{this.state.count}</p> <button id="btn">绑定点击事件</button> </> ) } componentDidMount(){ document.querySelector('#btn').addEventListener('click',()=>{ this.setState({ count: this.state.count + 1 }); console.log(this.state.count); }); } }
export default Count;
|