React元件通訊
概念:元件通訊就是
元件之間的資料傳遞
, 根據元件巢狀關係的不同,有不同的通訊手段和方法
- A-B 父子通訊
- B-C 兄弟通訊
- A-E 跨層通訊
父子通訊-父傳子
基礎實現
實現步驟
- 父元件傳遞資料 - 在子元件標籤上繫結屬性
- 子元件接收資料 - 子元件透過props引數接收資料
function Son(props){
return <div>{ props.name }</div>
}
function App(){
const name = 'this is app name'
return (
<div>
<Son name={name}/>
</div>
)
}
props說明
props可以傳遞任意的合法資料,比如數字、字串、布林值、陣列、物件、函式、JSX
props是隻讀物件
子元件只能讀取props中的資料,不能直接進行修改, 父元件的資料只能由父元件修改
特殊的prop-chilren
場景:當我們把內容巢狀在元件的標籤內部時,元件會自動在名為children的prop屬性中接收該內容
父子通訊-子傳父
核心思路:在子元件中呼叫父元件中的函式並傳遞引數
function Son({ onGetMsg }){
const sonMsg = 'this is son msg'
return (
<div>
{/* 在子元件中執行父元件傳遞過來的函式 */}
<button onClick={()=>onGetMsg(sonMsg)}>send</button>
</div>
)
}
function App(){
const getMsg = (msg)=>console.log(msg)
return (
<div>
{/* 傳遞父元件中的函式到子元件 */}
<Son onGetMsg={ getMsg }/>
</div>
)
}
兄弟元件通訊
實現思路: 藉助
狀態提升
機制,透過共同的父元件進行兄弟之間的資料傳遞
- A元件先透過子傳父的方式把資料傳遞給父元件App
- App拿到資料之後透過父傳子的方式再傳遞給B元件
// 1. 透過子傳父 A -> App
// 2. 透過父傳子 App -> B
import { useState } from "react"
function A ({ onGetAName }) {
// Son元件中的資料
const name = 'this is A name'
return (
<div>
this is A compnent,
<button onClick={() => onGetAName(name)}>send</button>
</div>
)
}
function B ({ name }) {
return (
<div>
this is B compnent,
{name}
</div>
)
}
function App () {
const [name, setName] = useState('')
const getAName = (name) => {
setName(name)
}
return (
<div>
this is App
<A onGetAName={getAName} />
<B name={name} />
</div>
)
}
export default App
跨層元件通訊
實現步驟:
- 使用
createContext
方法建立一個上下文物件Ctx - 在頂層元件(App)中透過
Ctx.Provider
元件提供資料 - 在底層元件(B)中透過
useContext
鉤子函式獲取消費資料
// App -> A -> B
import { createContext, useContext } from "react"
// 1. createContext方法建立一個上下文物件
const MsgContext = createContext()
function A () {
return (
<div>
this is A component
<B />
</div>
)
}
function B () {
// 3. 在底層元件 透過useContext鉤子函式使用資料
const msg = useContext(MsgContext)
return (
<div>
this is B compnent,{msg}
</div>
)
}
function App () {
const msg = 'this is app msg'
return (
<div>
{/* 2. 在頂層元件 透過Provider元件提供資料 */}
<MsgContext.Provider value={msg}>
this is App
<A />
</MsgContext.Provider>
</div>
)
}
export default App