默认情况下,react中的组件都是独立的个体,只能使用自身的数据信息,为实现一个功能的分工,通常会将一个功能拆分为几个不同的组件进行,这一过程中就不可避免的要共享组件的数据,让每个组件之间进行通信。
一、父子组件的通信
1.父传子的方式
步骤:
(1)父组件提供要进行通信的数据
(2)在父组件中使用子组件,并给子组件标签添加属性并设置值为父组件要进行传递的数据
(3)子组件接收父组件传递的数据
(1)父组件提供要通信的数据
function Father() {
// 1.设置父组件要传递的值
const father = 'This is Father-Component';
return (
<>
<div>父亲组件内容:{father}</div>
</>
)
}
(2)在父组件中传值
方式一、使用绑定属性的方式传值
function Father() {
// 1.设置父组件要传递的值
const father = 'This is Father-Component';
return (
<>
<div>父亲组件内容:{father}</div>
{/* 2.在子组件Son上绑定一个属性(可以为自定义的 如:message),属性的值(如:father)就是要传输给Son的内容 */}
<Son message={father}/>
</>
)
}
方式二、使用双标签的方式传值
function Father() {
// 1.设置父组件要传递的值
const father = 'This is Father-Component';
return (
<>
<div>父亲组件内容:{father}</div>
<Son>
{/* 使用双标签模式 这段在标签内部的代码会在 子组件中的参数props中的children里展示 */}
<div>This is Father-Component---双标签模式</div>
</Son>
</>
)
}
(3)子组件接收父组件的传值
使用props接收
// 3.子组件接收父组件传来的参数(自定义的),props 是一个对象
// 或是使用解构的方式{message}
// 注意:props是只读对象,不可以在子组件中进行修改,修改的原则:谁的数据谁修改
function Son(props) {
const son = 'This is Son-Component';
return (
<>
<div>儿子组件内容:{son}</div>
<div>父亲---儿子的内容:{props.message}</div>
</>
)
}
双标签模式的接收
function Son(props) {
const son = 'This is Son-Component';
return (
<>
<div>儿子组件内容:{son}</div>
<div>{props.children}</div>
</>
)
}
(4)运行效果
使用props传值的方式
使用双标签传值的方式
小结:父传子,即父组件准备数据并提供绑定标签属性的方式(或使用双标签传值的方式)传递给子组件,子组件再进行接收使用。
2.子传父的通信方式
步骤:
(1)父组件提供回调函数,并给子组件传参
(2)子组件调用传递来的回调函数,提供要传递的参数
(3)父组件接收子组件的传递
(1)子组件
// 使用解构的方式接收参数
function Child({ change }) {
let child = 'This is Child'
return (<>
<div>{child}</div>
{/* 调用change实质上是调用父亲中的函数 */}
{change(child)}
</>)
}
(2)父组件
function Dady() {
const dady = 'This is Father-Component'
const [state, setstate] = useState();
// 准备函数
function getSonData(data) {
console.log(data);
setstate(data);
}
return (
<>
<div>父组件的内容:{dady}</div>
<div>子传父的内容:{state}</div>
{/* 1.在父组件里准备一个回调函数,并在子组件里自定义一个属性进行接收 */}
<Child change={getSonData} />
</>
)
}
(3)运行效果
二、兄弟组件的通信
利用提升的思想,将共享的数据信息提交到公共的父组件中,再由父组件进行管理。
下面以A组件---> B组件为例进行示范。
分析:
A--->B 等价于 A---->父亲---->B
所以,A--->父亲之间使用子传父的通信,父亲--->B之间使用父传子的通信即可实现AB兄弟之间的通信。
(1)组件A
function A({ change }) {
const a = 'This is A';
change(a)
return (<>
<div>A原生数据:{a}</div>
</>)
}
(2)组件B
function B(props) {
const b = 'This is B';
return (<>
<div>B原生数据:{b}</div>
<div>B来自A数据:{props.msg}</div>
</>)
}
(3)公共父组件Father
function Father() {
const [state, setstate] = useState('');
// 子传父 准备函数
function getA(data) {
setstate(data)
}
return (<>
{/* 子组件A */}
<div>公共父组件接收来自A的数据:{state}</div>
<A change={getA} />
{/* 子组件B */}
<B msg={state} />
</>)
}
(4)运行效果
三、跨级通信
实现步骤:
1.引入createContext,useContext
2.创建createContext
如:const ctx = React.createContext();
3.在应用的顶层组件或某个需要提供数据的高层组件中使用Provider,并用value传递需要共享的数据
4.在任意深度的子组件中,使用hook函数 useContext,获取数
组件与组件之间跨越多层进行通信,使用createContext, useContext进行。
(1)引入reateContext, useContext
import { createContext, useContext } from 'react'
// 1. 引入createContext对象
(2)创建上下文对象
// 2.创建上下文对象
const ctx = createContext()
(3)定义顶层组件
在顶层用Provider方法包裹组件,确定上下文生效范围,(也可以只写一个组件,其余组件在这唯一的组件中进行使用)
提供value属性,并把需要提供给底层的数据作为value的值
export default function Top() {
const top = 'This is top';
return (
<>
<div>Top组件的值:{top}</div>
<ctx.Provider value={top}>
<A />
<B />
<C />
</ctx.Provider>
</>
)
}
(4)在任意深度的子组件中使用
使用hook函数useContext获取最上层组件的数据
下例 在A、B、C组件中均有使用
function A() {
const context = useContext(ctx);
return (
<div>A组件:{context}</div>
)
}
function B() {
const context = useContext(ctx);
return (<div>B组件:{context}</div>)
}
function C() {
const context = useContext(ctx);
return (
<div>C组件:{context}</div>
)
}