组件通信就是 组件之间的数据传递 , 根据组件嵌套关系的不同,有不同的通信手段和方法。
- A-B 父子通信
- B-C 兄弟通信
- A-E 跨层通信
父传子
- 父组件传递数据 – 在子组件标签上绑定属性
- 子组件接收数据 – 子组件通过props参数接收数据
function Son(props) {
return <div>This is Son {props.myName}</div>;
}
const App = () => {
const name = "这里是父组件的名称";
return (
<div className="app">
<Son myName={name} />
</div>
);
};
export default App;
props是只读对象
子组件只能读取props中的数据,不能直接进行修改, 父组件的数据只能由父组件修改
props可以传递任意的合法数据,比如数字、字符串、布尔值、数组、对象、函数、JSX
父传子-TS
组件定义代码
// 定义NoteCard组件的props类型接口
interface NoteCardProps {
review: string;
martText?: string;
}
const NoteCard: React.FC<NoteCardProps> = ({ review, martText }) => {
return (
<>
<div className="note-card">
<div className="review">{review}</div>
{martText && <div className="martText">{martText}</div>}
</div>
</>
);
};
export { NoteCard };
组件使用代码
<NoteCard
review="拥有一台赚钱机器,不是成为一台赚钱机器。"
martText="乐观主义当然是一种正面的品质,它会帮助你看到所有事物的积极面。但如果只有乐观主义而不具备其他品质的话,它也不会发挥很大作用。乐观主义经常被错当成自信。"
/>
子传父
核心思路:在子组件中调用父组件中的函数并传递参数
示例代码:
function Son(props) {
return (
<div>
<button onClick={props.logMsg}>点击</button>
</div>
);
}
const App = () => {
const logMsg = () => {
console.log("我是父组件中的方法");
};
return (
<div className="app">
<Son logMsg={logMsg}></Son>
</div>
);
};
export default App;
效果:点击按钮,会在控制台打印相关字符
兄弟组件通信
实现思路: 借助 状态提升
机制,通过共同的父组件进行兄弟之间的数据传递
- A组件先通过子传父的方式把数据传递给父组件App
- App拿到数据之后通过父传子的方式再传递给B组件
示例代码:
import { useState } from "react";
function SonA(props) {
const msg = `SonA 中设置的 fatherName`;
return (
<div>
<button onClick={() => props.getFatherName(msg)}>点击</button>
</div>
);
}
function SonB(props) {
return <div>{props.fatherName}</div>;
}
const App = () => {
const [fatherName, setFatherName] = useState("初始值");
const getFatherName = (name) => {
setFatherName(name);
};
return (
<div className="app">
<SonB fatherName={fatherName}></SonB>
<SonA getFatherName={getFatherName}></SonA>
</div>
);
};
export default App;
效果:
跨层级通信
- 使用
createContext
方法创建一个上下文对象Ctx - 在顶层组件(App)中通过
Ctx.Provider
组件提供数据 - 在底层组件(B)中通过
useContext
钩子函数获取消费数据
示例代码:
import { createContext, useContext } from "react";
// 1. createContext方法创建一个上下文对象
const MsgContext = createContext();
function Son() {
return (
<div>
this is Son Text
<GrandSon></GrandSon>
</div>
);
}
function GrandSon() {
// 3. 在底层组件 通过useContext钩子函数使用数据
const msg = useContext(MsgContext);
return <div>GrandSon, {msg}</div>;
}
const App = () => {
const msg = `This is app msg`;
return (
<div className="app">
{/* 2. 在顶层组件 通过Provider组件提供数据 */}
<MsgContext.Provider value={msg}>
this is app text
<Son></Son>
</MsgContext.Provider>
</div>
);
};
export default App;
效果: