React 组件通讯与插槽

摘要

本文总结几种常见的 react 组件通讯方式,帮助新手玩家快速完成开发任务。

父子组件通信

父组件传递数据给子组件:

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
// ParentComponent.jsx
import React from 'react';
import ChildComponent from './ChildComponent';

function ParentComponent() {
const message = "Hello from Parent";

return (
<div>
<h1>Parent Component</h1>
<ChildComponent message={message} />
</div>
);
}

export default ParentComponent;

// ChildComponent.jsx
import React from 'react';

function ChildComponent({ message }) {
return (
<div>
<h2>Child Component</h2>
<p>{message}</p>
</div>
);
}

export default ChildComponent;

子组件向父组件传递数据:

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
// ParentComponent.jsx
import React, { useState } from 'react';
import ChildComponent from './ChildComponent';

function ParentComponent() {
const [message, setMessage] = useState("");

const handleMessage = (msg) => {
setMessage(msg);
};

return (
<div>
<h1>Parent Component</h1>
<p>Message from Child: {message}</p>
<ChildComponent onMessage={handleMessage} />
</div>
);
}

export default ParentComponent;

// ChildComponent.jsx
import React from 'react';

function ChildComponent({ onMessage }) {
const sendMessage = () => {
onMessage("Hello from Child");
};

return (
<div>
<h2>Child Component</h2>
<button onClick={sendMessage}>Send Message to Parent</button>
</div>
);
}

export default ChildComponent;

兄弟组件通信

兄弟组件之间的通信通常通过提升状态到共同的父组件来实现。

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
// ParentComponent.jsx
import React, { useState } from 'react';
import FirstChild from './FirstChild';
import SecondChild from './SecondChild';

function ParentComponent() {
const [message, setMessage] = useState("");

return (
<div>
<h1>Parent Component</h1>
<FirstChild setMessage={setMessage} />
<SecondChild message={message} />
</div>
);
}

export default ParentComponent;

// FirstChild.jsx
import React from 'react';

function FirstChild({ setMessage }) {
const sendMessage = () => {
setMessage("Hello from First Child");
};

return (
<div>
<h2>First Child</h2>
<button onClick={sendMessage}>Send Message</button>
</div>
);
}

export default FirstChild;

// SecondChild.jsx
import React from 'react';

function SecondChild({ message }) {
return (
<div>
<h2>Second Child</h2>
<p>Message: {message}</p>
</div>
);
}

export default SecondChild;

使用 Context API 进行跨层级组件通信

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// MessageContext.js
import React, { createContext, useState } from "react";

export const MessageContext = createContext();

export const MessageProvider = ({ children }) => {
const [message, setMessage] = useState("Default Message");

return (
<MessageContext.Provider value={{ message, setMessage }}>
{children}
</MessageContext.Provider>
);
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// ParentComponent.jsx
import React from "react";
import { MessageProvider } from "./MessageContext";
import FirstChild from "./FirstChild";
import SecondChild from "./SecondChild";

function ParentComponent() {
return (
<MessageProvider>
<div>
<h1>Parent Component</h1>
<FirstChild />
<SecondChild />
</div>
</MessageProvider>
);
}

export default ParentComponent;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// FirstChild.jsx
import React, { useContext } from "react";
import { MessageContext } from "./MessageContext";

function FirstChild() {
const { setMessage } = useContext(MessageContext);

const sendMessage = () => {
setMessage("Hello from First Child via Context");
};

return (
<div>
<h2>First Child</h2>
<button onClick={sendMessage}>Send Message</button>
</div>
);
}

export default FirstChild;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// SecondChild.jsx
import React, { useContext } from "react";
import { MessageContext } from "./MessageContext";

function SecondChild() {
const { message } = useContext(MessageContext);

return (
<div>
<h2>Second Child</h2>
<p>Message: {message}</p>
</div>
);
}

export default SecondChild;

插槽(使用 props.children

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
// ParentComponent.jsx
import React from 'react';
import SlotComponent from './SlotComponent';

function ParentComponent() {
return (
<div>
<h1>Parent Component</h1>
<SlotComponent>
<p>This is a slot content from Parent</p>
</SlotComponent>
</div>
);
}

export default ParentComponent;

// SlotComponent.jsx
import React from 'react';

function SlotComponent({ children }) {
return (
<div>
<h2>Slot Component</h2>
<div>{children}</div>
</div>
);
}

export default SlotComponent;