React组件通信

46 阅读3分钟
实现一个嵌套关系
//项目根组件
//App -> index.js -> public/index.html(root)


//useState实现计数器
import React, { useState } from'react'

//子组件
function Son(){
  return (
    <div className='son'>this is son</div>
  )
}

//父组件
function App() {
  return (
    <div className="App">
      <Son/>
    </div>
  );
}



export default App;

image.png

父传子
  1. 子组件标签绑定属性
  2. 子组件接收数据,props的参数
//项目根组件
//App -> index.js -> public/index.html(root)


//useState实现计数器
import React, { useState } from'react'

//子组件
function Son(props){
  console.log(props)
  return (
    <div className='son'>this is son</div>
  )
}

//父组件
function App() {
  const name = 'this is app name'
  return (
    <div className="App">
      <Son name={name}/>
    </div>
  );
}



export default App;

image.png

我们可以看到在子组件中定义的形参props是一个对象,里面包含name属性

//项目根组件
//App -> index.js -> public/index.html(root)


//useState实现计数器
import React, { useState } from'react'

//子组件
function Son(props){
  console.log(props)
  return (
    <div className='son'>this is son ,{props.name}</div>
  )
}

//父组件
function App() {
  const name = 'this is app name'
  return (
    <div className="App">
      <Son name={name}/>
    </div>
  );
}



export default App;

image.png

props

  1. 可以是数字、字符串、布尔值、数组、对象、函数、JSX
  2. props是只读对象,子组件只能读取props中的数据,不能直接进行修改,父组件的数据只能由父组件修改
children

场景:当我们把内容嵌套在子组件标签中时,父组件会自动在名为children的prop属性中接收该内容

//项目根组件
//App -> index.js -> public/index.html(root)


//useState实现计数器
import React, { useState } from'react'

//子组件
function Son(props){
  console.log(props)
  return (
    <div className='son'>this is son ,{props.name}</div>
  )
}

//父组件
function App() {
  const name = 'this is app name'
  return (
    <div className="App">
      <Son name={name}>
        children-this is children
      </Son>
    </div>
  );
}



export default App;

我们在Son标签内部写了一部分内容,此时在看子组件的props输出什么:

image.png

比之前多了一个children属性,而值就是我们在父组件中给子组件标签内部添加的内容

子传父

核心思路:在子组件中调用父组件中的函数并传递参数

//项目根组件
//App -> index.js -> public/index.html(root)


//useState实现计数器
import React, { useState } from'react'

//子组件
function Son({getMsg}){
  const sendMsg = 'this is son msg'
  return (
    <div className='son'>
      <button onClick={()=>{getMsg(sendMsg)}}>子组件</button>
    </div>
  )
}

//父组件
function App() {
  const name = 'this is app name'
  const getMsg = (msg)=>{
    console.log('子组件传递过来的数据' + msg)
  }
  return (
    <div className="App">
      <Son name={name} getMsg={getMsg}>
        children-this is children
      </Son>
    </div>
  );
}



export default App;

image.png

这样就可以实现子组件将数据传递给父组件中了

兄弟组件通信

使用状态提升实现兄弟组件通信

实现思路:借助“状态提升”机制,通过父组件进行兄弟组件之间的数据传递

  1. A组件先通过子传父的方式把数据传递给父组件APP
  2. App拿到数据后通过父传子的方式再传递给B组件
//项目根组件
//App -> index.js -> public/index.html(root)


//useState实现计数器
import React, { useState } from'react'

//子组件
function SonA({getMsg}){
  const sendMsg = 'this is sonA msg'
  return (
    <div className='son'>
      <button onClick={()=>{getMsg(sendMsg)}}>A子组件</button>
    </div>
  )
}

//子组件
function SonB(props){
  return (
    <div className='son'>
      子组件B {props.msg}
    </div>
  )
}

//父组件
function App() {
  const [msg,setMsg] = useState('')
  const getMsg = (msg)=>{
    setMsg(msg)
  }
  return (
    <div className="App">
      <SonA getMsg={getMsg}>
        children-this is children
      </SonA>
      <SonB msg={msg}>
        children-this is children
      </SonB>
    </div>
  );
}



export default App;

image.png

我们看到A组件按钮点击后,传出来的数据被B组件接收到了

使用content机制实现跨层级组件通信
  1. 使用createContent方法创建一个上下文对象Ctx
  2. 在顶层组件(APP)中通过Ctx.Provider组件提供数据
  3. 在底层组件(B)中通过useContent钩子函数获取数据
//项目根组件
//App -> index.js -> public/index.html(root)


//useState实现计数器
import React, { createContext, useContext, useState } from'react'
const MsgContent = createContext()
//子组件
function SonB(){
  const content = useContext(MsgContent)
  console.log(content);
  return (
    <div className='son'>
      子组件B {content}
    </div>
  )
}

//子组件
function SonA(){
  return (
    <div className='son'>
      子组件A
      <SonB/>
    </div>
  )
}



//父组件
function App() {
  const msg = 'this is app msg'

  return (
    <div className="App">
      <MsgContent.Provider value={msg}>
        <SonA/>
      </MsgContent.Provider> 
    </div>
  );
}



export default App;

image.png

我们看到APP组件内的msg就传递给B组件中了