🔥你不得不了解的React组件之间通信
你不得不了解的React组件之间通信
我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第4篇文章 点击查看文章详情 🚀🚀
前言
react组件之间通信,作为前端面试最最最频繁的考点之一,与其反反复复去看去背知识点,还不如自己写篇文章总结一下来的有趣~🎉🎉
基本概念
提到react组件之间通信,脑海中自然而然就要想到五种
基本情况
- 父组件向子组件通信
- 子组件向父组件通信
- 兄弟组件通信
- 跨级组件通信
即父组件向子组件的子组件通信,向更深层子组件通信。
- 非嵌套关系的组件通信
即没有任何包含关系的组件,包括兄弟组件以及不在同一个父级中的非兄弟组件。
父子组件通信
废话不多说,我们直接看下面的例子👇
效果图
实现过程
// App.jsx
import { useState } from 'react'
import Father from './Father'
function App() {
return (
<div className="App">
<Father/>
</div>
)
}
export default App
// Father.jsx
import React from 'react'
import { useState } from 'react'
import Child from './Child'
export default function Father() {
const [state,setState] = useState('state')
return (
<div>
<Child state={state} setState={setState}></Child>
</div>
)
}
// Child.jsx
import React from 'react'
export default function Child(props) {
const { state,setState } = props
const onButtonClick = () => {
setState('后代知道了')
}
return (
<div>
{ state }
<button onClick={onButtonClick}>后代知道了</button>
</div>
)
}
-
在父子组件通信中,我们需要了解:
-
父组件负责请求和处理数据
-
子组件没有自己的状态,主要负责展示数据,和调用父组件修改数据的方法
-
数据的改变发生在父组件里,父组件数据改变后,子组件重新渲染
-
在这个例子中不仅体现了父组件向子组件通信,还体现了子组件向父组件的通信
-
父组件向子组件通信
父组件自身定义了
state
属性,通过props
属性传递给了子组件,在子组件中,用props就可以获取到这个state值 -
子组件向父组件的通信
子组件通过父组件传递过来的
setState
方法,改变父组件中state
的值,实现了在子组件中改变了父组件状态
兄弟组件之间通信
效果图
实现过程
// App.jsx
import { useState } from 'react'
import Channel from './Channel'
function App() {
return (
<div className="App">
<Channel/>
</div>
)
}
export default App
// Channel.jsx
import React, { useState } from 'react'
import ComA from './ComA';
import ComB from './ComB';
export default function Channel() {
// 父组件负责状态管理
const [stateA, setStateA] = useState("A");
const [stateB, setStateB] = useState("B");
return (
<div>
<ComA stateA={stateA} setStateB={setStateB} setStateA={setStateA}/>
<ComB stateB={stateB} setStateA={setStateA} setStateB={setStateB}/>
</div>
)
}
// ComA.jsx
import React from 'react'
export default function ComA(props) {
const { stateA, setStateA, setStateB} = props
const onButtonClick = () => {
setStateB(stateA)
}
const onResetButtonClick = () => {
setStateA("A")
}
return (
<div>
{stateA}
<button onClick={onButtonClick}>把B变成A</button>
<button onClick={onResetButtonClick}>还原A</button>
</div>
)
}
// ComB.jsx
import React from 'react'
export default function ComB(props) {
const { stateB, setStateA, setStateB} = props
const onButtonClick = () => {
setStateA(stateB)
}
const onResetButtonClick = () => {
setStateA("B")
}
return (
<div>
{stateB}
<button onClick={onButtonClick}>把A变成B</button>
<button onClick={onResetButtonClick}>还原B</button>
</div>
)
}
兄弟组件(ComA,ComB)
间通信,通过父组件(Channel)
作为桥梁,仍然用的是props
跨级组件通信
效果图
实现过程
// App.jsx
import { useState } from 'react'
import Ancestor from './Ancestor'
function App() {
return (
<div className="App">
<Ancestor/>
</div>
)
}
export default App
// Little.jsx
import React, { createContext, useState } from 'react'
import Little from './Litter'
// 1.使用createContext创建并初始化
export const Context = createContext();
function Child() {
return (
<div>
<Little />
</div>
)
}
export default function Ancestor() {
const [state, setState] = useState("state")
return (
// 2.在Provider圈定的范围内,传入读操作和写操作对象,
// 然后可以使用上下文
<Context.Provider value={{state, setState}}>
<div>
<Child />
</div>
</Context.Provider>
)
}
// Litter.jsx
import React, {useContext} from 'react'
import { Context } from './Ancestor'
export default function Litter() {
// 3. 最后使用useContext接受上下文,因为传入的是对象,
// 则接受的也应该是对象
const { state, setState } = useContext(Context)
const onButtonClick = () => {
setState('后代知道了');
}
return (
<div>
{state}
<button onClick={onButtonClick}> 后代知道了</button>
</div>
)
}
又回到我们之前的定义
跨级组件通信
即父组件向子组件的子组件通信,向更深层子组件通信。
向更深层子组件通信,我们很容易联想到用父子组件中props传值,但是当我们业务很多,第一层向第十层,第一百层通信,难道也傻乎乎的一直用props传下去?
🙅🙅🙅NO!
这个时候 Context
来发挥作用了!
Context
提供了一个无需为每层组件手动添加props
,就能在组件树间进行数据传递的方法。Context
设计目的是为了共享那些对于一个组件树而言是“全局”的数据。使用context
,我们可以避免通过中间元素传递props
非嵌套关系的组件通信
这里就比较复杂了,需要使用到redux进行一个全局的状态管理。
或者使用 useContext
+ useReducer
进行redux代替。
对这个感兴趣的朋友可以去了解一下,这里就不展开说了,抱歉了~
小结
-
父组件向子组件通信:
父组件通过
props
向子组件传递需要的信息。父传子是在父组件中直接绑定一个正常的属性,这个属性就是指具体的值,在子组件中,用props
就可以获取到这个值 -
子组件向父组件通信
props+回调函数
的方式,使用公共组件进行状态提升。子传父是先在父组件上绑定属性设置为一个函数
,当子组件需要给父组件传值的时候,则通过props
调用该函数将参数传入到该函数当中,此时就可以在父组件中的函数中接收到该参数了,这个参数则为子组件传过来的值 -
兄弟组件通信:
可以找到这两个兄弟节点共同的父节点, 结合父子间通信方式进行通信。
-
跨级组件通信
即父组件向子组件的子组件通信,向更深层子组件通信。
使用
props
,利用中间组件层层传递,但是如果父组件结构较深,那么中间每一层组件都要去传递props,增加了复杂度,并且这些props
并不是中间组件自己需要的。使用
context
,context
相当于一个大容器,我们可以把要通信的内容放在这个容器中,这样不管嵌套多深,都可以随意取用,对于跨越多层的全局数据可以使用context实现。 -
非嵌套关系的组件通信
即没有任何包含关系的组件,包括兄弟组件以及不在同一个父级中的非兄弟组件。
可以通过redux等进行全局状态管理
最后
又小小地总结了一个特别基础的问题
不求别的,就希望面试的时候能够和面试官多扯上那么一分钟
或者就是不要总是看了忘,忘了看。
⭐⭐⭐
最后的最后 all in all
点赞 + 关注 + 收藏 = 学会了
转载自:https://juejin.cn/post/7145423740350758949