React 组件通信

分类:

父子组件通信

​   无论父组件传递是props还是state,子组件都是通过props接收


import React, {Component,Fragment} from 'react'
import Son from './Son'
class Father extends Component{
constructor(){
super()
this.state={
name:'zhangsan'
}
}
render(){
return(
<Fragment>
<p> 这里是父组件 </p>
<hr/>
{/* <Son name={this.state.name}/> */}
<Son {...this.state}/>
</Fragment>
)
}
}
export default Father



import React, {Component,Fragment} from 'react'
class Son extends Component{
render(){
return(
<Fragment>
<p> 这里是子组件 </p>
<p>{this.props.name}</p>
</Fragment>
)
}
}
export default Son


子父组件通信

​   父组件传递方法给子组件,子组件调用父组件传递过来的方法
​   注意: 自己的状态自己更改


import React, {Component,Fragment} from 'react'
import Son from './Son'
class Father extends Component{
constructor(){
super()
this.state={
name:'zhangsan'
}
}
changeName=( val )=>{
this.setState({
name:val
})
}
render(){
return(
<Fragment>
<p> 这里是父组件 </p>
<hr/>
<Son changeName={this.changeName}/>
<p>name: { this.state.name }</p>
</Fragment>
)
}
}
export default Father


import React, {Component,Fragment} from 'react'
class Son extends Component{
render(){
return(
<Fragment>
<p> 这里是子组件 </p>
<button onClick={()=>{this.props.changeName('lisi')}}>改名</button>
</Fragment>
)
}
}
export default Son

非父子组件通信

​   ref链
​     1. ref = ‘xxx’ this.refs.xxx
​     2. ref = { el => this.xxx = el } this.xxx推荐


import React, {Component,Fragment} from 'react'
import Son from './Son'
import Girl from './Girl'
class Father extends Component{
constructor(){
super()
this.state={
name:'zhangsan'
}
}
kick=()=>{
console.log(this)
this.son.change()
}
render(){
return(
<Fragment>
<p> 这里是父组件 </p>
<hr/>
<Son ref={ el => this.son = el }/>
<hr/>
<Girl ref={ el => this.girl = el} kick={this.kick}/>
</Fragment>
)
}
}
export default Father

import React, {Component,Fragment} from 'react'
class Son extends Component{
constructor(){
super()
this.state={
flag:false
}
}
change = () => {
this.setState({
flag:!this.state.flag
})
}
render(){
return(
<Fragment>
<p> 这里是子组件 </p>
{ this.state.flag && <p>(╥╯^╰╥)(╥╯^╰╥)(╥╯^╰╥)</p>}
</Fragment>
)
}
}
export default Son
import React, {Component,Fragment} from 'react'
class Girl extends Component{
render(){
return(
<Fragment>
<p> 这里是girl组件 </p>
<button onClick={this.props.kick}>揍</button>
</Fragment>
)
}
}
export default Girl

跨组件通信

​   context
​   使用流程
​     - 创建上下文 React.createContext()
​     - 使用上下文包裹目标组件的父组件 
​     - 在目标组件中先定义一个静态属性 static contextType = MoneyContext
​     - 通过 this.context来使用数据

// 定义一个上下文
import React from 'react'
export const Context= React.createContext()


import React, {Component,Fragment} from 'react'
import Father from './Father'
import {Context} from './context'
class GrandFather extends Component{
constructor(){
super()
this.state={
name:'Shirley'
}
}
render(){
return(
<Fragment>
<p>这里是爷爷组件</p>
<Context.Provider value={this.state.name}>
{/* 这里用解构会报错 */}
<Father/>
</Context.Provider>
</Fragment>
)
}
}
export default GrandFather



import React, {Component,Fragment} from 'react'
import Son from './Son'
class Father extends Component{
constructor(){
super()
this.state={
name:'zhangsan'
}
}
render(){
return(
<Fragment>
<p> 这里是父组件 </p>
<hr/>
<Son/>
</Fragment>
)
}
}
export default Father



import React, {Component,Fragment} from 'react'
import { Context } from './context'
class Son extends Component{
static contextType = Context
render(){
return(
<Fragment>
<p> 这里是子组件 </p>
<p>爷爷传过来的数据:{this.context}</p>
</Fragment>
)
}
}
export default Son


多组件状态共享

​   Flux
​   redux
​   mobx ( 阿里 )

父组件与子组件通信

  • 父组件将自己的状态传递给子组件,子组件当做属性来接收,当父组件更改自己状态的时候,子组件接收到的属性就会发生改变
  • 父组件利用ref对子组件做标记,通过调用子组件的方法以更改子组件的状态,也可以调用子组件的方法…
    子组件与父组件通信
  • 父组件将自己的某个方法传递给子组件,在方法里可以做任意操作,比如可以更改状态,子组件通过this.props接收到父组件的方法后调用。
    跨组件通信
    在react没有类似vue中的事件总线来解决这个问题,我们只能借助它们共同的父级组件来实现,将非父子关系装换成多维度的父子关系。react提供了context api来实现跨组件通信, React 16.3之后的contextapi较之前的好用。
    实例,使用context 实现购物车中的加减功能
// counterContext.js
import React, { Component, createContext } from 'react'
const {
Provider,
Consumer: CountConsumer
} = createContext()
class CountProvider extends Component {
constructor () {
super()
this.state = {
count: 1
}
}
increaseCount = () => {
this.setState({
count: this.state.count + 1
})
}
decreaseCount = () => {
this.setState({
count: this.state.count - 1
})
}
render() {
return (
<Provider value={{
count: this.state.count,
increaseCount: this.increaseCount,
decreaseCount: this.decreaseCount
}}
>
{this.props.children}
</Provider>
)
}
}
export {
CountProvider,
CountConsumer
}
// 定义CountButton组件
const CountButton = (props) => {
return (
<CountConsumer>
// consumer的children必须是一个方法
{
({ increaseCount, decreaseCount }) => {
const { type } = props
const handleClick = type === 'increase' ? increaseCount : decreaseCount
const btnText = type === 'increase' ? '+' : '-'
return <button onClick={handleClick}>{btnText}</button>
}
}
</CountConsumer>
)
}
// 定义count组件,用于显示数量
const Count = (prop) => {
return (
<CountConsumer>
{
({ count }) => {
return <span>{count}</span>
}
}
</CountConsumer>
)
}
// 组合
class App extends Component {
render () {
return (
    <CountProvider>
<CountButton type='decrease' />
<Count />
<CountButton type='increase' />
</CountProvider>
  )
}
}

复杂的非父子组件通信在react中很难处理,多组件间的数据共享也不好处理,在实际的工作中我们会使用flux、redux、mobx来实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值