React组件通信、父传子实现、子传父、兄弟组件通信、跨组件通信 Context

组件通信

组件通信的意义

组件是独立封闭的单元,默认情况下组件只能使用自己的数据(state)
组件化开发的过程中,完整的功能会拆分多个组件,在这个过程中不可避免要传递一些数据
为了能让各组件之间进行互相沟通,数据传递,这个过程就是组件通信

  1. 父子关系 - 最重要的
  2. 兄弟关系 - 自定义事件模式产生技术方法 eventBus / 通过共同的父组件通信
  3. 其他关系 - mobx / redux / 基于 hook 的方案

父传子实现

学习目标: 实现父子通信中的父传子,把父组件中的数据传递给子组件
实现步骤:

  1. 父组件提供要传递的数据 -> state
  2. 给子组件标签添加属性值为 state 中的数据
  3. 子组件中通过props接收父组件传过来的数据
  4. 类组件使用 this.props 获取 props 对象
  5. 函数式组件直接通过参数获取 props 对象
    代码实现
import React from 'react'
// APP 父组件
// son 子组件
class SonC extends React.Component {
  render() {
    return <div>我是类子组件:{this.props.msg}</div>
  }
}
function SonF(props) {
  return <div>我是函数子组件:{props.msg}</div>
}
class App extends React.Component {
  state = {
    Message: 'this is message',
  }
  render() {
    return (
      <>
        <SonC msg={this.state.Message} />
        <SonF msg={this.state.Message} />
      </>
    )
  }
}
export default App

props 说明

学习目标: 知道 props 传递时的一些注意事项

  1. props 是只读对象(readonly)
    根据单项数据流要求,子组件只能读取 props 中的数据,不能进行修改
    js this.props.msg = 'new msg' //不行,不能修改
  2. props 可以传递任意数据
    数字、字符串、布尔值、数组、对象、函数、jsx
import React from 'react'
// APP 父组件
// son 子组件
class SonC extends React.Component {
  render() {
    return <div>我是类子组件:{this.props.msg}</div>
  }
}
function SonF(props) {
  /*
  简洁方法:使用解构赋值 省略props
  1.
  const {msg,age,cd,child,list,obj} = props
  2.function SonF({msg,age,cd,child,list,obj}) {}
  */
  const { msg, age, cd, child, list, obj, getmsg } = props
  return (
    <>
      <div>
        我是函数子组件:{msg}{age}{cd}{props.list}{child}
      </div>
      {props.list.map((item) => (
        <p key={item}>{item}</p>
      ))}
      {obj.name}
      <button onClick={getmsg}>click</button>
    </>
  )
}
class App extends React.Component {
  state = {
    Message: 'this is message',
    list: [1, 2, 3],
    obj: {
      name: 'jack',
      age: '19',
    },
  }
  getmsg = () => {
    console.log('getmsg')
  }
  render() {
    return (
      <>
        <SonC msg={this.state.Message} />
        <SonF
          msg={this.state.Message}
          list={this.state.list}
          age={23}
          obj={this.state.obj}
          cd={() => {
            console.log(1)
          }}
          child={<span>look me</span>}
          getmsg={this.getmsg}
        />
      </>
    )
  }
}
export default App

子传父

实现方法:
子组件调用父组件传递的函数,并且将想要传递的数据当作函数的实参

import React from 'react'
// APP 父组件
// son 子组件
//子组件调用父组件传递的函数,并且将想要传递的数据当作函数的实参
function SonF(props) {
  /*调用方法2
  function clickHandler(){
    props.getmsg("this is son msg")
  }
  */
  return (
    <button
      onClick={() => {
        props.getmsg('this is son msg')
      }}>
      click
    </button>
  )
}
class App extends React.Component {
  state = {
    Message: 'this is message',
  }
  getmsg = (date) => {
    this.setState({
      Message: date,
    })
  }
  render() {
    return (
      <>
        <div>{this.state.Message}</div>
        <SonF getmsg={this.getmsg} />
      </>
    )
  }
}
export default App

兄弟组件通信

思路: 通过组件状态提升机制,利用共同的父组件实现兄弟组件通信
实现方法: 1.将共享状态提升到最近的父组件中,由公共组件管理这个状态

  • 父组件获取 B 子组件的数据
  • 父组件将获取的数据传给 A 子组件
import React from 'react'
// APP 父组件
// SonA SonB 子组件
// 目标 将B中的数据传输给A
function SonA(props) {
  return <div>this is SonA message/{props.msg}</div>
}
function SonB(props) {
  const Bmsg = 'this is Bmsg'
  return (
    <div>
      this is SonA message
      <button
        onClick={() => {
          props.getBmsg(Bmsg)
        }}>
        click
      </button>
    </div>
  )
}
class App extends React.Component {
  state = {
    Message: 'this is message',
  }
  getBmsg = (msg) => {
    console.log(msg)
    // 将获取的B的数据交给Message
    this.setState({
      Message: msg,
    })
  }
  render() {
    return (
      <>
        <SonB getBmsg={this.getBmsg} />
        <SonA msg={this.state.Message} />
      </>
    )
  }
}
export default App

跨组件通信 Context

**学新目标:**了解 Context 机制解决的问题和使用步骤
问题场景
React组件通信、父传子实现、子传父、兄弟组件通信、跨组件通信 Context_第1张图片

如上图,为一个 React 形成的嵌套组件树,如果我们要从 App 组件向任意下层组件传递数据,采用一层一层 props 往下传递会很繁琐,我们该怎么办呢
实现步骤:

  1. 创建 Context 对象导出 Provider 和 Consumer 对象

      const {Provider , Consumer} = createContext()
    
  2. 使用 Provider 包裹根组件提供的数据

      <Provider value={this.state.message}>
        {/* 根组件*/}
      </Provider>
    
  3. 需要用到数据的组件使用 Consumer 包裹获取数据

      <Consumer>
        {value => /* 基于Context值进行渲染 */}
      </Consumer>
    

代码实现:

import React, { createContext } from 'react'
//1.
const { Provider, Consumer } = createContext()
//App->A->B
//App数据->B
function ConA() {
  return (
    <div>
      this is A
      <ConB />
    </div>
  )
}
function ConB() {
  return (
    // 3. 通过Consumer使用数据
    <div>
      this is B<Consumer>{(value) => <span>{value}</span>}</Consumer>
    </div>
  )
}
class App extends React.Component {
  state = {
    msg: 'this is AppMsg',
  }
  render() {
    return (
      // 通过Provider提供数据
      <Provider value={this.state.msg}>
        <div>
          <ConA />
        </div>
      </Provider>
    )
  }
}
export default App

你可能感兴趣的:(react.js,javascript,前端)