こんにちは
親コンポーネントのstateに保持されている値を、子コンポーネントで変えるには、親コンポーネント側で、その値を変えるハンドラを用意して、これを子コンポーネントに prop 経由で渡し、子コンポーネントでそのハンドラを使うというのがお決まりのやり方です。これは Hooks が導入されてからも変わりません。
ご質問の例だと、親コンポーネントSample
の状態として持つべき(ダイアログから入力される)名前の値と、それと変更するハンドラをuseState
で取得し、それらを子コンポーネントに渡して、子ではそれらを適切に使えばよいです。
具体的な修正案を、以下のcodesandboxに挙げました。
上記の修正前のほうは、ご質問に挙げられているコードを転記したもので、これに適宜コードを追加して、修正後のコードを作りました。修正後では、親コンポーネントにCard を追加し、ここに子コンポーネントのダイアログから入力された名前を表示させるようにしました。
上記の修正案による、修正前と修正後の差分を以下に挙げておきます。
Sample (src/index.js)
diff
1--- before/src/index.js 2020-03-15 00:23:00.000000000 +0900
2+++ after/src/index.js 2020-03-15 00:10:28.000000000 +0900
3@@ -1,23 +1,43 @@
4-import React from "react";
5+import React, { useState } from "react";
6 import ReactDOM from "react-dom";
7 import Grid from "@material-ui/core/Grid";
8+import Card from "@material-ui/core/Card";
9+import CardContent from "@material-ui/core/CardContent";
10 import { makeStyles } from "@material-ui/styles";
11 import FormDialog from "./FormDialog";
12
13 const useStyles = makeStyles({
14 parent: {},
15- root_: {}
16+ root_: {},
17+ result: {
18+ backgroundColor: "#eee",
19+ marginBottom: 30
20+ },
21+ name: {
22+ fontWeight: "bold",
23+ color: "darkblue"
24+ }
25 });
26
27 function Sample() {
28 const classes = useStyles();
29+ const [name, setName] = useState("");
30+
31 return (
32 <div className={classes.parent}>
33 <Grid container className={classes.root_} spacing={2}>
34 <Grid item xs={12}>
35+ <Card className={classes.result}>
36+ <CardContent>
37+ 入力された名前:
38+ <span className={classes.name}>{name}</span>
39+ </CardContent>
40+ </Card>
41+ </Grid>
42+ <Grid item xs={12}>
43 <Grid container justify="center" spacing={2}>
44 <Grid key={0} item>
45- <FormDialog />
46+ <FormDialog defaultValue={name} onSubmit={setName} />
47 </Grid>
48 </Grid>
49 </Grid>
FormDialog (src/FormDialog.jsx)
diff
1--- before/src/FormDialog.jsx 2020-03-15 00:23:00.000000000 +0900
2+++ after/src/FormDialog.jsx 2020-03-15 00:10:28.000000000 +0900
3@@ -7,14 +7,20 @@
4 import TextField from "@material-ui/core/TextField";
5 import DialogActions from "@material-ui/core/DialogActions";
6
7-export default function FormDialog() {
8+export default function FormDialog({ defaultValue, onSubmit }) {
9 const [open, setOpen] = React.useState(false);
10+ const inputRef = React.useRef(null);
11
12 const handleClickOpen = () => {
13 setOpen(true);
14 };
15
16- const handleClose = () => {
17+ const handleCancel = () => {
18+ setOpen(false);
19+ };
20+
21+ const handleSubmit = () => {
22+ onSubmit(inputRef.current.value);
23 setOpen(false);
24 };
25
26@@ -25,7 +31,7 @@
27 </Button>
28 <Dialog
29 open={open}
30- onClose={handleClose}
31+ onClose={handleCancel}
32 aria-labelledby="form-dialog-title"
33 >
34 <DialogTitle id="form-dialog-title">名前登録</DialogTitle>
35@@ -38,13 +44,15 @@
36 label="Name"
37 type="email"
38 fullWidth
39+ defaultValue={defaultValue}
40+ inputRef={inputRef}
41 />
42 </DialogContent>
43 <DialogActions>
44- <Button onClick={handleClose} color="primary">
45+ <Button onClick={handleCancel} color="primary">
46 Cancel
47 </Button>
48- <Button onClick={handleClose} color="primary">
49+ <Button onClick={handleSubmit} color="primary">
50 OK
51 </Button>
52 </DialogActions>
以上参考になれば幸いです。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/03/15 01:10
2020/03/15 01:14
2020/03/15 01:31 編集
2020/03/15 01:46