React 非父子组件通信方式

一、非父子组件通信方式

1 状态提升(中间人模式)

React中的状态提升概况来说,就是将多个组件需要共享的状态提升到它们最近的父组件上,在父组件上改变这个状态然后通过props分发给子组件

import React, { Component } from 'react'

export default class Tenth extends Component {
  state = {
    title: ''
  }
  render() {
    return (
      <div>
        <One childTitle={this.state.title} onEvent={(e) => {
          this.setState({
            title: e
          })
        }} />
        <Two twoTitle={this.state.title} />
      </div>
    )
  }
}
//One组件向Two组件传信息
class One extends Component {
  state = {
    oneTitle: "rain"
  }
  render() {
    return (
      <div>
        <button onClick={() => {
          this.props.onEvent(this.state.oneTitle)
        }}>点击</button>
      </div>
    )
  }
}


class Two extends Component {
  render() {
    return (
      <div style={{ backgroundColor: "yellow", width: '100px', height: "100px" }}>{this.props.twoTitle}</div>
    )
  }
}

2 发布订阅模式实现

subsrcibe()存入函数到list数组等待运行,调用publish()函数运行list数组中全部函数。

下面的代码中,仅在Two组件的constructor()函数中运行了一次subsrcibe()函数,所以list数组中仅有一个函数,每次运行publish()函数时,运行(text) => { this.setState({ info: text }) }

import React, { Component } from 'react'

// 调度中心
var obj = {
  list: [],
  // 每次调用此函数,存入一个函数到list
  subsrcibe(callback) {
    // console.log(callback)
    this.list.push(callback)
  },
  // 每次调用此函数,运行list数组里的全部函数
  publish(text) {
    console.log(text)
    // 遍历所有的list,将回调函数执行
    this.list.forEach(callback => {
      callback && callback(text)
    })
  }
}

export default class Eleventh extends Component {
  state = {
    list: [1, 2, 3, 4, 5]
  }
  render() {
    return (
      <div>
        {
          this.state.list.map(item => <One key={item} msg={item} ></One>)
        }
        <Two />
      </div>
    )
  }
}


class One extends Component {
  render() {
    return (
      <div style={{ backgroundColor: "green", height: "20px", width: "20px" }} onClick={() => {
        obj.publish(this.props.msg)
      }
      }>
        <div>{this.props.msg}</div>
      </div >
    )
  }
}

class Two extends Component {
  constructor() {
    super()
    obj.subsrcibe((text) => {
      this.setState({
        info: text
      })
    })
  }
  state = {
    info: ''
  }
  render() {
    return (
      <div style={{ backgroundColor: 'yellow', width: '100px', height: '100px' }}>
        {this.state.info}
      </div>
    )
  }
}

3 context状态树传参(官方方法)

  1. 先定义全局context对象
  2. 根组件引入GlobalContext,并使用GlobalContext.Provider(生产者)
  3. 任意组件引入GlobalContext并调用Context,使用GlobalContext.Consumer(消费者)
import React, { Component } from 'react'

const GlobalContext = React.createContext() //创建context对象

export default class Tewlfth extends Component {
  state = {
    user: 'rain',
    sex: true
  }
  render() {
    return (
      <GlobalContext.Provider value={{
        user: this.state.user,
        sex: this.state.sex,
        changeUser: (value) => {
          this.setState({
            sex: !value
          })
        }
      }}>
        <div>
          <One />
          <Two />
        </div>
      </GlobalContext.Provider>
    )
  }
}
class One extends Component {
  render() {
    return (
      <GlobalContext.Consumer>
        {
          (value) => {
            return (
              <div style={{ backgroundColor: "green", height: "100px", width: "100px" }} >
                <div>{value.user}</div>
                <button onClick={() => {
                  value.changeUser(value.sex)
                }}>点击</button>
              </div >
            )
          }
        }
      </GlobalContext.Consumer >
    )
  }
}

class Two extends Component {
  render() {
    return (
      <GlobalContext.Consumer>
        {
          (value) => {
            return (
              <div style={{ backgroundColor: "yellow", width: "100px", height: '100px' }}>{value.sex ? "男" : "女"}</div>
            )
          }
        }
      </GlobalContext.Consumer>
    )
  }
}

你可能感兴趣的:(笔记,javascript,前端,react)