组件通信

React组件通信

组件

dom组件 react支持的htmlsvg标签

props

什么是props html属性的功能

dom属性

类名 className

样式

1
2
3
4
5
6
7
8
style={
{
width:'100vh',
height:100,
backgroundColor:'grey'
//带-的写成驼峰
}
}

也可以书写变量

1
2
3
4
5
6
7
8
9
const imgStyle={
width:'100vh',
height:100,
backgroundColor:'grey'
}
return(
<div>
<img style={imgStyle}/>
</div>)

jsx展开语法

把所有属性书写为一个变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import image from './logo.svg'
const imgData={
className='small',
style:{
width:'100vh',
height:100,
backgroundColor:'grey'
} }
return(
<div>
<img
//src标签不能提出
src={image}
{...imgData}
/>
</div>
)

自定义组件react的props

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function Artcile()
{
return(
<div>
<h2>111</h2>
<p>222</p>
</div>
)
}
export default function App()
{
return(
<>
<Article/>
<Article/>
<Article/>
<Article/>
</>


)
}

如果对组件的结构逻辑 样式复用

内容不复用的话 可以写成

对组件内容定制

步骤

1.对父元素(上面的App)进行请求 请求功能所需要的数据

2.创建组件

3.把数据传给组件

父组件向子组件传普通值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
function Detail()
{
return(
<>
<p>{content}</p>
<p>状态:{active?'显示':'隐藏'}</p>
</>
)
}
function Artcile({acticleData})
//采用解构
{
return(
<div>
<h2>{title}</h2>
<Detail {...articleData}
></Detail>
</div>
)
//此时Article没用到content和active
//但是Detail用到了 可以在Article先不传 直接传给Detail
}
export default function App()
{const articleData={
title:'1',
detailData:{
content:'1',active:true
}
}
return(
<>
<Article
{...acticleData}
/>
<Article
title="2"
content="2"
active
/>
<Article
title="3"
content="3"
active
/>
</>


)
}

父组件向子组件传jsx

插槽 jsx作为props传给子组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
function List ({children,title,footer=       
<div>默认底部</div>})
//此时footer需要一个默认值
{
return(
<>
<h2>{title}</h2>
<ul>
{children}
</ul>
{footer}
</>
)
}
//如果需要在列表加元素
export default function App ()
{
return (
<>
//之前是通过props传递 现在通过children
//自动接受组件开始和接受的内容
<List
title="列表1"
footer={
<p>这是底部内容1</p>
}>
<li>内容1</li>
<li>内容2</li>
<li>内容3</li>
</List>

<List
title="列表2"
footer={<p>这是底部内容2</p>}>
<li>内容A</li>
<li>内容B</li>
<li>内容C</li>
</List>
<List
title="列表3"
//此时没设置footer会显示默认值
>
<li>内容X</li>
<li>内容Y</li>
<li>内容Z</li>
</List>
</>
)
}

子组件向父组件传值

父组件给子组件一个自定义事件的设置 再通过事件触发后向父组件传递参数来设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
function Detail ({onActive}){
//希望告诉父组件内部状态 在handleClick函数使用的变更 所以在handleClick加入onACtive事件并传入status
const [status,setStatus]=useState(false)
function handleClick()
{
setStatus(!status)
onActive(status)
//每次状态变更 传递一个新值 传递到function App()
}
return (
<div>
<button onClick={handleClick}>按钮</button>
<p
style={{display;staus?
'block':'none'}}>
Detail的内容</p>

</div>
)
}
export default function App(){
function handleActive(status){
console.log(status)
}
return(
<>
//如果希望父组件能接受子组件的状态的话需要给子组件设置一个自定义属性(onActive)可以理解为事件 用代码决定在何时触发

<Detail
onActive={handleActive}></Detail>
</>

)
}

同级组件传值

在父组件进行中转

多层级传值

提供了一个多级属性穿透的hook

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import {useState} from "react"
export function Section ({children})
{
//获取上一级level
const level=useContext(LevelContext)
return (

<section className="section">
<LevelContect.Provider
value={
level+1
}>
{children}</LevelContect.Provider>

</section>
)
}
export function Heading({level,children})
{
const level=useContext(LevelContext)
//设置之后此时全为h1(若默认值是1)
//但是h1和section嵌套会使h1显示出从大到小的样式
switch(level){
case 1:
return <h1>{children}</h1>
case 2:
return <h2>{children}</h2>
case 3:
return <h3>{children}</h3>
case 4:
return <h4>{children}</h4>
case 4:
return <h4>{children}</h4>
case 5:
return <h5>{children}</h5>
case 6:
return <h6>{children}</h6>
}
}
const LevelContext=createContext(0)
//不能直接用 通过useContext
export default function App (){
return(
<div>
<section>
<Heading >主标题</Heading>
<section>
<Heading >副标题</Heading>
<Heading >副标题</Heading>
<Heading >副标题 </Heading>
<section>
<Heading>子标</Heading>
<Heading>子标</Heading>
<Heading >子标</Heading>
<section>
<Heading >子子标题</Heading>
<Heading>子子标题</Heading>
<Heading >子子标题</Heading>
<section>
<Heading >子子子标题</Heading>
<Heading >子子子标题</Heading>
<Heading >子子子标题</Heading>
<section>>
<Heading >子子子子标题 </Heading>
<Heading >子子子子标题 </Heading>
<Heading >子子子子标题 </Heading>
</section>
</section>
</section>
</section>
</section>
</section>
</div>)
}

Ps:可能会出现都是h1标签但是大小却不同的情况

sectionh1嵌套时候自然出现的状态

如何更改useContext能够获取到的level信息

useContext创建的对象LevelContext提供一个Provider

context提供值的一个方式


组件通信
http://example.com/2024/02/17/组件通信/
Author
Shanyujia
Posted on
February 17, 2024
Licensed under