React父子组件间的通信是如何进行的
本篇内容介绍了“React父子组件间的通信是如何进行的”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
父子组件通信方式
(1)传递数据(父传子)与传递方法(子传父)
(2)ref标记(父组件拿到子组件的引用,从而调用子组件的方法)
父传子
使用 props属性,传入props
this.props.数据
//父组件 <Field label="用户名"></Field>//子组件 <label>{this.props.label}</label>
子传父
父组件向子组件传一个函数,然后通过子组件中这个函数的回调,拿到子组件穿过的值
this.props.函数名()
//子组件<input onChange={(evt)=>{ this.props.onChangeEvent(evt.target.value)}}></input>//父组件 <Field onChangeEvent={(value)=>{ console.log(value) }}></Field>
ref标记(传递数据)
在组件身上绑定ref,直接通过 this.username.current 获得整个组件,this.username.current.state获得子组件内state数据
this.ref名.current
//子组件中 state={ value:'' } <input onChange={(evt)=>{ this.setState({ value:evt.target.value })}}></input>//父组件username = React.createRef()<Field ref={this.username}></Filed>....console.log(this.username.current.state.value)
父组件中清除子组件的值:在子组件中定义修改state函数,父组件中调用此函数来实现
clear(){ this.setState({ value:'' })} <input value={this.state.value}></input>....................this.username.current.clear()//父
非父子组件通信方式
状态提升(兄弟通信)
React中的状态提升概括来说,就是将多个组件需要共享的状态提升到它们最近的父组件上,在父组件上改变这个状态然后通过props分发给子组件
发布订阅模式
兄弟组件AB,子组件A将值传给B组件,在子组件A中发布,在子组件B中订阅,,此方法适合任意关系的通信
调度中心bus:
var bus={list:[],//放入所有的订阅//订阅 subscribe(callback){ this.list.push(callback) //callback为注册订阅的回调函数 }//发布publish(){ }}
订阅消息
//创建订阅的回调函数subscribe(callback){ console.log(callback); this.list.push(callback)}//订阅者bus.subscribe((value)=>{ console.log(111,value);})bus.subscribe((value)=>{ console.log(222,value);})
发布消息
//创建bus(调度中心)中的发布函数publish(text){ //遍历所有的list,将回调函数执行 // console.log(this.list); this.list.forEach(callback=>{ callback && callback(text) }) }//发布者setTimeout(()=>{ bus.publish('沉默')},0)
bus.publish调用时,传入参数,触发bus中publish函数并接收到数据即text,调用callback回调函数,传入text,此时调用者subscribe将收到参数为value,即将组件A数据传入组件B中
context状态树传参(跨组件方案)
Context 提供了一种在组件之间共享此类值的方式,是“全局”的数据,而不必显式地通过组件树的逐层传递 props。
context上下文对象来管理公共状态,来实现数据的修改
创建context对象
const GlobalContext = React.createContext()
创建提供数据的父组件Provider
给Provider组件设置value属性,需要传递到后代组件中的数据作为value的值
当Provider发生数据value变更时,会触发到Consumer发生渲染,所有被其包裹的子组件都会发生渲染(render被调用)
//格式state={ info:'111'}render(){ return( <GlobalContext.Provider value={{ //key:value或key:函数 }}> <div>父组件内容</div> </GlobalContext.Provider> )}
创建接受数据的子孙组件Consumer
//格式render(){ return( <GlobalContext.Consumer> { (value)=>{ return( <div onClick={()=>{ }}> </div> ) } } </GlobalContext.Consumer> )}
在子孙组件A中调用Provider中的回调函数
某些时候需要内部组件去更新Context的数据,只需要向上下文添加回调函数即可
//子组件A中 调用回调函数,传递数据value.chageInfo(synopsis)//父组件state={ info:111}......................................<GlobalContext.Provider value={{ "name":"说名字", "info":this.state.info, chageInfo:(content)=>{ this.setState({ info:content }) }}}>
全局定义状态,并修改状态
子孙组件B中接收Provider的数据
<GlobalContext.Consumer> { (value)=><div className="filmDetail"> //接受Provider的数据 detail-{value.info} </div> } </GlobalContext.Consumer>
实现了将组件A的值传给了组件B的值
React插槽
作用:为了复用;一定程度减少父子通信
children实现插槽
在React组件中直接包裹一些html标签,html标签内容是否会出现呢?
<Child> <div>111</div> <div>22</div> <div>333</div></Child>
由上图可见,被包裹的html标签并未被渲染出来,这是因为当读取到Child组件时,会重新渲染页面覆盖被包裹的html标签;而我们可以在Child组件中留下html标签的位置,以便来显示被包裹的html,这种做法即为 插槽
语法
使用props的固定属性children在Child组件中占位
this.props.children//该属性中包含子组件标签开始到结束之间的内容
父组件的子组件标签中写入要插入到子组件的html标签
export default class App extends Component { render() { return ( <div> <Child> <div>111</div> <div>22</div> <div>333</div> </Child> </div> ) }}
在子组件中放入该标签
class Child extends Component{ render(){ return( <div> child {this.props.children} </div> ) }}
多个元素的children
如果children中有多个元素,那么children为一个数组,数组中放着所有存放的内容
//父组件<Child> <div>111</div> <div>22</div> <div>333</div></Child>//子组件<div> child <h4>以下获得所有内容</h4> {this.props.children} <h4>以下获得数组其中的元素</h4> {this.props.children[1]}</div>
注意:以上方法实现了 可以通过被 插槽的内容来直接操作父组件,以此给子组件传递数据(被 插入的内容连同数据一起插入子组件中)。
“React父子组件间的通信是如何进行的”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341