React 中的组件通信

124 阅读2分钟

组件通信

  • 概念:组件通信就是组件间的数据传递,根据组件嵌套关系的不同,有不同的通信方法
  • 类别
    • 父子通信
    • 兄弟通信
    • 跨层通信

父子通信

父子组件通信中关于 props 说明

  • props 可以传递任意数据(数字、字符串、布尔值、数组、对象、函数、JSX)

    <div className="App">
          <Son
            info={info}
            age={20}
            name={"jack"}
            isTrue={false}
            list={["vue", "react"]}
            obj={{ name: "xiaoming" }}
            thing={() => {
              console.log(123);
            }}
            child={<div>this is div</div>}
          ></Son>
        </div>
    
  • props 是只读对象

    子组件只能读取 props 中的数据,不能直接进行修改,父组件的数据只能由父组件修改

  • 实现步骤:

    • 父组件传递数据 - 在子组件标签上绑定属性
    • 子组件接收数据 - 子组件通过 props 参数接收数据
    function Son(props) {
      // 子组件通过 props 接收数据
      // props : 对象里包含了父组件传递过来的所有的数据
      return <div> this is son, {props.info}</div>;
    }
    
    function App() {
      // 定义内容
      const info = "this is APP";
      return (
        <div className="App">
          <Son info={info}></Son>
        </div>
      );
    }
    
    export default App;
    

父子组件通信中特殊的 Prop children

  • 场景:当我们把内容嵌套在子组件标签中,父组件会自动在名为 children 的 prop 属性中接收该内容
function Son(props) {
  return (
    <div>
      react,
      {/* 子组件接收 */}
      {props.children}
    </div>
  );
}

function App() {
  return (
    <div className="App">
      <Son>
        <div>this is div</div>
      </Son>
    </div>
  );
}

export default App;

父子组件通信中的 子传父

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

    function Son({ onGetSonMesg }) {
      const sonMsg = "this is son msg";
      return (
        <div>
          react,
          <button onClick={() => onGetSonMesg(sonMsg)}> Button </button>
        </div>
      );
    }
    
    function App() {
      const [msg, setMsg] = useState("");
    
      const getMsg = (msg) => {
        console.log(msg);
        // 更新 UI 显示
        setMsg(msg);
      };
      return (
        <div className="App">
          {msg}
          {/* 规范写法,父传子传递的是函数,方法为on 开头*/}
          <Son onGetSonMesg={getMsg}></Son>
        </div>
      );
    }
    
    export default App;
    

兄弟通信

截屏2024-02-23 16.42.47.png

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

    • A 组件先通过子传父的方式把数据传递给父组件 APP
    • APP 拿到数据后在通过父传子的方式再传递给B 组件
  • 示例

    function A({ onAMsg }) {
      const AInfo = "A Info";
    
      return (
        <div>
          A 组件
          <button onClick={() => onAMsg(AInfo)}> send </button>{" "}
        </div>
      );
    }
    
    function B(props) {
      return <div> B 组件 {props.info}</div>;
    }
    
    function App() {
    
      const [info, setInfo] = useState("")
    
      const getAMsg = (msg) => {
        console.log(msg);
        setInfo(msg)
      };
    
      return (
        <div className="App">
          {/* 子传父 */}
          <A onAMsg={getAMsg}></A>
    
          {/* 父传子 */}
          <B info={info}></B>
        </div>
      );
    }
    
    export default App;
    

跨层通信

  • 使用 context 机制实现跨层通信

    截屏2024-02-23 17.26.07.png

  • 核心思路:

    • 使用 createContext 方法创建一个上下文对象 Ctx
    • 在顶层组件(APP)中通过 Ctx.Provider 组件提供数据
    • 在底层组件(B)中通过 useContext 钩子函数获取消费数据
  • 示例

    import { createContext} from "react";
    
    // 创建一个 context
    const MsgContext = createContext();
    
    function A() {
      return (
        <div>
          A 组件
          <B></B>
        </div>
      );
    }
    
    
    function B() {
      // 使用 useContext 钩子函数使用数据
      const msg = useContext(MsgContext)
      return <div> B 组件 {msg}</div>;
    }
    
    function App() {
      const msg = "infomation";
    
      return (
        <div className="App">
          {/* 使用 Provider 提供数据 */}
          <MsgContext.Provider value={msg}>
            APP
            <A></A>
          </MsgContext.Provider>
        </div>
      );
    }
    
    export default App;