react Hook 提供 useContext 函数,方便深层次嵌套组件在不使用状态管理器的情况下实现组件间的数据共享,不需要再像之前使用 Customer 消费者函数来获取数据。当我们需要修改 context 的数据时,只需要通过 context 传递一个函数即可。

在父组件中,通过 Provider 提供数据,并在创建 context 时候声明一个用于修改数据的函数。

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
// postPage.tsx

import React, { useState, createContext } from "react";
import { Card } from "antd";
import Comments from "./comments";

export const CommentContext = createContext({
name: "",
comments: "",
onChangeContext: (values: any) => {}
});

const PostPage: React.FC<{}> = props => {
const [contextData, setContextData] = useState({
name: "",
comments: ""
});

const onChangeContext = (v: any) => {
console.log("执行了改变共享Context数据", v);
setContextData({ ...contextData, ...v });
};

const values: any = {
...contextData,
onChangeContext
};

return (
<div>
<Card title="文章评论">
<CommentContext.Provider value={values}>
<Comments />
</CommentContext.Provider>
</Card>
</div>
);
};

export default PostPage;

在子组件中显示一个表单,用于提交留言信息,导入父组件中声明的 context 对象,调用 context 中的函数传入对于的表单数据。

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
// comments.tsx

import React, { useContext } from "react";
import { Button, Card, Form, Input } from "antd";

import { CommentContext } from "./postPage";
import ShowComments from "./showComments";

const layout = {
labelCol: { span: 4 },
wrapperCol: { span: 16 }
};
const tailLayout = {
wrapperCol: { offset: 4, span: 16 }
};

const Comments: React.FC<{}> = props => {
const { onChangeContext } = useContext(CommentContext);

const onFinish = (values: any) => {
onChangeContext({ comments: values.comment, name: values.username });
console.log("Success:", values);
};

return (
<div>
<Card title="评论显示">
<ShowComments />
</Card>
<Card title="留下足迹">
<Form {...layout} name="comments" onFinish={onFinish}>
<Form.Item
label="用户"
name="username"
rules={[{ required: true, message: "Please input your username!" }]}
>
<Input />
</Form.Item>

<Form.Item
label="评论"
name="comment"
rules={[{ required: true, message: "Please input your comment!" }]}
>
<Input />
</Form.Item>

<Form.Item {...tailLayout}>
<Button type="primary" htmlType="submit">
提交
</Button>
</Form.Item>
</Form>
</Card>
</div>
);
};

export default Comments;

最后在评论显示区显示对于的内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// showComments.tsx

import React, { useContext } from "react";

import { CommentContext } from "./postPage";

const ShowComments: React.FC<{}> = props => {
const { name, comments } = useContext(CommentContext);

return (
<div>
<p>{name && comments && `${name}${comments}`}</p>
</div>
);
};

export default ShowComments;