🎀个人主页:努力学习前端知识的小羊
感谢你们的支持:收藏🎄 点赞🍬 加关注🪐
父子组间通信
1.父传子
props
父组件向子组件传递props,子组件通过参数接受props值
//父组件 <Field label="用户名" type="text" /> //子组件 <div> <label>{this.props.label}</label> <input type={this.props.type}></input> </div>
2.子传父
通过回调函数 callback
//子组件 <button onClick={()=>{ console.log("子通知父,让父的isshow取反",this.props.event); this.props.event() }}>click</button> //父组件 handleEvent=()=>{ this.setState({ isshow:!this.state.isshow }) console.log("父组件的event函数"); } render() { return ( <div> <Navbar event={this.handleEvent}/> </div> ) }
3.ref
子组件设置ref属性,父组件通过this.ref名称.current来获取到子组件的数据来进行调用
//子组件 state={ value:'' } render(){ return <input onChange={(evt)=>{ this.setState({ value:evt.target.value }) }}></input> } //父组件 username = React.createRef() password = React.createRef() render() { return ( <div> //给子组件绑定ref <Field label="用户名" type="text" ref={this.username}/> <Field label="密码" type="password" ref={this.password}/> <button onClick={()=>{ //获取子组件的state.vlue console.log(this.username.current.state.value, this.password.current.state.value); }}>登录</button> </div> ) }
非父子组件通信
1.状态提升(中间人状态)
React中的状态提升概括来说,就是将多个组件需要共享的状态提升到他们最近的父组件上,在父组件上改变这个状态然后通过props分发给子组件。
//父组件 render() { return ( <div> { this.state.filmlist.map(item => <FilmItem key={item.filmId} {...item} onEvent={(value)=>{ this.setState({ info:value }) }}></FilmItem> ) } <Film_detail info={this.state.info}></Film_detail> </div> ) } //子组件 class FilmItem extends Component{ render(){ let {name,poster,synopsis,grade} = this.props return <div className='filmitem' onClick={()=>{ this.props.onEvent(synopsis) }}> <img src={poster} alt={name}/> <h4>{name}</h4> <div>观众评分:{grade}</div> </div> } } class Film_detail extends Component{ render(){ return <div className='film_detail'> {this.props.info} </div> } }
2.发布订阅模式
存在一个调度中心bus,此方法适用于任何组件之间的通信
调度中心bus
var bus = { list:[], // 订阅 subscribe(callback){ // console.log(); this.list.push(callback) }, // 发布 publish(text){ this.list.forEach(callback=>{ callback && callback(text) }) } }
订阅消息
//创建订阅的回调函数 subscribe(callback){ // console.log(); this.list.push(callback) }, // 订阅者 bus.subscribe((value)=>{ console.log('1111',value); }) bus.subscribe((value)=>{ console.log("22222",value); }) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 发布消息 // 创建bus的中的发布函数 publish(text){ this.list.forEach(callback=>{ callback && callback(text) }) } // 发布者 setTimeout(()=>{ bus.publish("111") },0) setTimeout(()=>{ bus.publish("222") },1000) setTimeout(()=>{ bus.publish("333") },2000) 1
bus.publish调用时,传入参数,触发bus中publish函数并接收到数据即text,调用callback回调函数,传入text,此时调用者subscribe将收到参数为value,即将组件A数据传入组件B中
3.context状态树传参
先创建context对象
const GlobalContext = React.createContext() //创建context对象
根组件引入GlobalContext,并使用GlobalContext.Provider(生产者)
<GlobalContext.Provider value={{ call:"打电话", sms:"短信", info:this.state.info, changeInfo:(value)=>{ this.setState({ info:value }) } }}> <div> { this.state.filmlist.map(item => <FilmItem key={item.filmId} {...item} ></FilmItem> ) } <Film_detail></Film_detail> </div> </GlobalContext.Provider>
其他组件引入GlobalContext并调用context,使用GlobalContext.Consumer
//组件1 <GlobalContext.Consumer> { (value)=>{ return <div className='filmitem' onClick={()=>{ value.changeInfo(synopsis) }}> <img src={poster} alt={name}/> <h4>{name}</h4> <div>观众评分:{grade}</div> </div> } } </GlobalContext.Consumer> //组件2 <GlobalContext.Consumer> { (value)=> <div className='film_detail'> detail-{value.info} </div> } </GlobalContext.Consumer>
注意:GlobalContext.Consumer内必须是回调函数,通过context方法改变根组件状态
context优缺点:
优点:跨组件访问数据
缺点: react组件树种某个上级组件shouldComponetUpdate返回false,当context更新时,不会引起下级组件更新
React插槽
使用props的固定属性children在Child组件中占位
作用:
1.为了复用
2.一定程度减少父子通信
单个插入
//子组件写入this.props.children,为插入部分留下位置 class Swiper extends Component{ render(){ return <div> {this.props.children} </div> } } //父组件写入要插入子组件的内容 <Swiper> <div>111111</div> <div>222222</div> <div>333333</div> </Swiper>
多个插入
class Child extends Component{ render(){ return <div> //子组件定义插入的顺序 {this.props.children[0]} {this.props.children[1]} {this.props.children[2]} </div> } } //父组件写入要插入子组件的内容 <Child > <div> 11111111 </div> <div>222222</div> <div>33333333</div> { // } </Child>
希望对大家有所帮助,期待你们的支持✨✨✨