Reactでアプリを作成しました【7】【マルチステップの入力フォーム①】

##【要件】

####1. 基本情報入力画面

(1) 性別と生年月日を入力できる
(2) 『進む』ボタン

####2. アンケート画面

(1) 最初に表示されている設問は１つのみ
(2) 設問に答えると次の設問が表示される
(3) 『戻る』ボタンと『進む』ボタン

####3. 相談内容入力画面

(1) Textareaに自由に入力できる
(2) 『戻る』ボタンと『進む』ボタン
(3) 『進む』ボタンは動作しなくても良い

####4. 確認画面

(1) 入力した内容が表示される
(2) 『戻る』ボタンと『送信』ボタン
(3) 『送信』ボタンは動作しなくても良い

##【作成にあたり学習した事】
- React Routerを使用したページ遷移
- Reduxを使用した状態管理

##1. 基本情報入力画面

####create React App でアプリの雛形を作成する。

```
$ npx create-react-app <アプリ名>
```

####事前準備をする。
#####Material-UI および React Hook Form v7 を利用するため、事前にライブラリをインストールする。

```
$ npm install @mui/material @emotion/react @emotion/styled
$ npm install @mui/material @mui/styled-engine-sc styled-components
$ npm install react-hook-form
$ git diff -p
:
snip
:
diff --git a/package.json b/package.json
index f61e3cb..9c49442 100644
--- a/package.json
+++ b/package.json
@@ -3,11 +3,13 @@
   "version": "0.1.0",
   "private": true,
   "dependencies": {
+    "@material-ui/core": "^4.12.2",
     "@testing-library/jest-dom": "^5.14.1",
     "@testing-library/react": "^11.2.7",
     "@testing-library/user-event": "^12.8.3",
     "react": "^17.0.2",
     "react-dom": "^17.0.2",
+    "react-hook-form": "^7.12.1",
     "react-scripts": "4.0.3",
     "web-vitals": "^1.1.2"
   },
```

####『ファイルタイプ別にグループ化する』方法を用いてソースを管理するため components ディレクトリを src ディレクトリ配下に配置する。

```
$ mkdir src/components
```

####ベースとなる画面構成を作成する

#####自動生成された App.js を、Header コンポーネントと Content コンポーネントで構成するためにテキストエディターで下記のように編集する。

```App.js
import { Grid } from '@mui/material';
import Header from './components/Header';
import Content from './components/Content';

function App() {
  return (
    <Grid container direction="column">
      <Header />
      <div style={{ padding: 30 }}>
        <Content />
      </div>
    </Grid>
  );
}
export default App;
```

####Header コンポーネントと Content コンポーネントを定義するため、ファイルを用意する。

```
$ touch src/components/Header.js
$ touch src/components/Content.js
```

```Header.js
import React from "react";
import { AppBar, Toolbar } from "@mui/material";

const Header = () => {
  return (
    <AppBar position="static" style={{ backgroundColor: "primary" }}>
      <Toolbar>React課題 ②</Toolbar>
    </AppBar>
  );
};

export default Header;
```

####Content.js に Stepper コンポーネントを配置する。
#####テキストエディターに戻って、Content.js を編集する。
#####『進む』『戻る』『送信』ボタン作成する
※内容は、Material-UI 公式ドキュメントに掲載のサンプルのソースコードをベースにしする。

getStepContent 関数は、React が管理している Stepper コンポーネントのインデックス番号（activeStep）に応じたコンテンツを取得する処理を記述する。そのため、各インデックス番号に応じたコンテンツ（コンポーネント）を下記のように返す。

```Content.js
import React from "react";
import { Grid } from "@mui/material";
import Stepper from "@mui/material/Stepper";
import Step from "@mui/material/Step";
import StepLabel from "@mui/material/StepLabel";
import Button from "@mui/material/Button";
import Typography from "@mui/material/Typography";

function getSteps() {
  return ["お客様の情報を入力してください", "以下にお答えください", "ご相談ください","以下の内容をご確認ください"];
}

function getStepContent(stepIndex) {
  switch (stepIndex) {
    case 0:
      return "フォーム　1 のコンテンツを表示";
    case 1:
      return "フォーム　2 のコンテンツを表示";
    case 2:
      return "フォーム　3 のコンテンツを表示";
    case 3:
      return "フォーム　4 のコンテンツを表示";
    default:
      return "Unknown stepIndex";
  }
}

function Content() {
  const [activeStep, setActiveStep] = React.useState(0);
  const steps = getSteps();
  const handleNext = () => {
    setActiveStep((prevActiveStep) => prevActiveStep + 1);
  };
  const handleBack = () => {
    setActiveStep((prevActiveStep) => prevActiveStep - 1);
  };
  const handleReset = () => {
    setActiveStep(0);
  };
  return (
    <Grid container>
      <Grid sm={2} />
      <Grid lg={8} sm={8} spacing={10}>
        <Stepper activeStep={activeStep} alternativeLabel>
          {steps.map((label) => (
            <Step key={label}>
              <StepLabel>{label}</StepLabel>
            </Step>
          ))}
        </Stepper>
        {activeStep === steps.length ? (
          <div>
            <Typography>全ステップの表示を完了</Typography>
            <Button onClick={handleReset}>リセット</Button>
          </div>
        ) : (
          <div>
            <Typography>{getStepContent(activeStep)}</Typography>
            <Button disabled={activeStep === 0} onClick={handleBack}>
              戻る
            </Button>
            <Button variant="contained" color="primary" onClick={handleNext}>
              {activeStep === steps.length - 1 ? "送信" : "次へ"}
            </Button>
          </div>
        )}
      </Grid>
    </Grid>
  );
}
export default Content;
```

##1.基本情報入力画面　2.アンケート画面　3. 相談内容入力画面
####case 0: return 1.基本情報入力画面; case 1: return 2.アンケート画面;
####case 2: return 3.相談内容入力画面; を編集する。

```Content.js
import React from "react";
import { Grid } from "@mui/material";
import Stepper from "@mui/material/Stepper";
import Step from "@mui/material/Step";
import StepLabel from "@mui/material/StepLabel";
import Button from "@mui/material/Button";
import Typography from "@mui/material/Typography";
import Radio from "@mui/material/Radio";
import RadioGroup from "@mui/material/RadioGroup";
import FormControlLabel from "@mui/material/FormControlLabel";
import FormControl from "@mui/material/FormControl";
import FormLabel from "@mui/material/FormLabel";
import Tooltip from "@mui/material/Tooltip";
import TextField from "@mui/material/TextField";
import InputLabel from "@mui/material/InputLabel";
import Select from "@mui/material/Select";

function getSteps() {
  return ["お客様の情報を入力してください", "以下にお答えください", "ご相談ください"];
}

function getStepContent(stepIndex) {
  switch (stepIndex) {
    case 0:
      return (
        <>
          <div>
            <FormControl component="fieldset">
              <FormLabel component="legend">- 性別 -</FormLabel>
              <RadioGroup row aria-label="gender" name="row-radio-buttons-group">
                <FormControlLabel value="male" control={<Radio />} label="男性" />
                <FormControlLabel value="female" control={<Radio />} label="女性" />
              </RadioGroup>
            </FormControl>
          </div>
          <div>
            <FormLabel component="legend">- 生年月日 -</FormLabel>
            <FormControl sx={{ m: 1, minWidth: 120 }}>
              <InputLabel htmlFor="grouped-native-select">year</InputLabel>
              <Select native defaultValue="" id="grouped-native-select" label="Grouping">
                <option aria-label="None" value="" />
                <optgroup label="year">
                  <option value={1}>　1990</option>
                  <option value={2}>　1991</option>
                  <option value={3}>　1992</option>
                  <option value={4}>　1993</option>
                  <option value={5}>　1994</option>
                  <option value={6}>　1995</option>
                  <option value={7}>　1996</option>
                  <option value={8}>　1997</option>
                  <option value={9}>　1998</option>
                  <option value={10}>　1999</option>
                  <option value={11}>　2000</option>
                  <option value={12}>　2001</option>
                  <option value={13}>　2002</option>
                  <option value={14}>　2003</option>
                  <option value={15}>　2004</option>
                  <option value={16}>　2005</option>
                  <option value={17}>　2006</option>
                  <option value={18}>　2007</option>
                  <option value={19}>　2008</option>
                  <option value={20}>　2009</option>
                  <option value={21}>　2010</option>
                  <option value={22}>　2011</option>
                  <option value={23}>　2012</option>
                  <option value={24}>　2013</option>
                  <option value={25}>　2014</option>
                  <option value={26}>　2015</option>
                  <option value={27}>　2016</option>
                  <option value={28}>　2017</option>
                  <option value={29}>　2018</option>
                  <option value={30}>　2019</option>
                  <option value={31}>　2020</option>
                  <option value={32}>　2021</option>
                </optgroup>
              </Select>
            </FormControl>
            <FormControl sx={{ m: 1, minWidth: 120 }}>
              <InputLabel htmlFor="grouped-native-select">month</InputLabel>
              <Select native defaultValue="" id="grouped-native-select" label="Grouping">
                <option aria-label="None" value="" />
                <optgroup label="month">
                  <option value={1}> 1</option>
                  <option value={2}> 2</option>
                  <option value={3}> 3</option>
                  <option value={4}> 4</option>
                  <option value={5}> 5</option>
                  <option value={6}> 6</option>
                  <option value={7}> 7</option>
                  <option value={8}> 8</option>
                  <option value={9}> 9</option>
                  <option value={10}> 10</option>
                  <option value={11}> 11</option>
                  <option value={12}> 12</option>
                </optgroup>
              </Select>
            </FormControl>
            <FormControl sx={{ m: 1, minWidth: 120 }}>
              <InputLabel htmlFor="grouped-native-select">day</InputLabel>
              <Select native defaultValue="" id="grouped-native-select" label="Grouping">
                <option aria-label="None" value="" />
                <optgroup label="day">
                  <option value={1}> 1</option>
                  <option value={2}> 2</option>
                  <option value={3}> 3</option>
                  <option value={4}> 4</option>
                  <option value={5}> 2</option>
                  <option value={6}> 6</option>
                  <option value={7}> 7</option>
                  <option value={8}> 8</option>
                  <option value={9}> 9</option>
                  <option value={10}> 10</option>
                  <option value={11}> 11</option>
                  <option value={12}> 12</option>
                  <option value={13}> 13</option>
                  <option value={14}> 14</option>
                  <option value={15}> 15</option>
                  <option value={16}> 16</option>
                  <option value={17}> 17</option>
                  <option value={18}> 18</option>
                  <option value={19}> 19</option>
                  <option value={20}> 20</option>
                  <option value={21}> 21</option>
                  <option value={22}> 22</option>
                  <option value={23}> 23</option>
                  <option value={24}> 24</option>
                  <option value={25}> 25</option>
                  <option value={26}> 26</option>
                  <option value={27}> 27</option>
                  <option value={28}> 28</option>
                  <option value={29}> 29</option>
                  <option value={30}> 30</option>
                  <option value={31}> 31</option>
                </optgroup>
              </Select>
            </FormControl>
          </div>
        </>
      );
    case 1:
      return (
        <div>
          <FormControl component="fieldset">
            <FormLabel component="legend">現在、生命保険に加入されていますか？</FormLabel>
            <RadioGroup row aria-label="gender" name="row-radio-buttons-group">
              <FormControlLabel value="yes" control={<Radio />} label="はい" />
              <FormControlLabel value="no" control={<Radio />} label="いいえ" />
            </RadioGroup>

            <FormLabel component="legend">
              現在、入院中ですか。また、3ヶ月以内に医師の診察・検査の結果、入院・手術をすすめられたことがありますか？
            </FormLabel>
            <RadioGroup row aria-label="gender" name="row-radio-buttons-group">
              <FormControlLabel value="yes" control={<Radio />} label="はい" />
              <FormControlLabel value="no" control={<Radio />} label="いいえ" />
            </RadioGroup>

            <FormLabel component="legend">
              過去、5年以内に病気やケガで手術を受けたことまたは継続して７日以上の入院をしたことはありますか？
            </FormLabel>
            <RadioGroup row aria-label="gender" name="row-radio-buttons-group">
              <FormControlLabel value="yes" control={<Radio />} label="はい" />
              <FormControlLabel value="no" control={<Radio />} label="いいえ" />
            </RadioGroup>
          </FormControl>
        </div>
      );
    case 2:
      return (
        <Grid container>
          <Grid sm={2} />
          <Grid lg={8} sm={8} spacing={10}>
            <Tooltip title="ご相談内容を記入することができます" placement="top-start" arrow>
              <TextField
                label="ご相談内容"
                fullWidth
                margin="normal"
                rows={4}
                multiline
                variant="outlined"
                placeholder="その他ご要望等あれば、ご記入ください"
              />
            </Tooltip>
          </Grid>
        </Grid>
      );
    default:
      return "Unknown stepIndex";
  }
}

function Content() {
  const [activeStep, setActiveStep] = React.useState(0);
  const steps = getSteps();
  const handleNext = () => {
    setActiveStep((prevActiveStep) => prevActiveStep + 1);
  };
  const handleBack = () => {
    setActiveStep((prevActiveStep) => prevActiveStep - 1);
  };
  const handleReset = () => {
    setActiveStep(0);
  };
  return (
    <Grid container>
      <Grid sm={2} />
      <Grid lg={8} sm={8} spacing={10}>
        <Stepper activeStep={activeStep} alternativeLabel>
          {steps.map((label) => (
            <Step key={label}>
              <StepLabel>{label}</StepLabel>
            </Step>
          ))}
        </Stepper>
        {activeStep === steps.length ? (
          <div>
            <Typography>全ステップの表示を完了</Typography>
            <Button onClick={handleReset}>リセット</Button>
          </div>
        ) : (
          <div>
            <Typography>{getStepContent(activeStep)}</Typography>
            <Button disabled={activeStep === 0} onClick={handleBack}>
              戻る
            </Button>
            <Button variant="contained" color="primary" onClick={handleNext}>
              {activeStep === steps.length - 1 ? "送信" : "次へ"}
            </Button>
          </div>
        )}
      </Grid>
    </Grid>
  );
}
export default Content;  
```

##2. アンケート画面を編集

#####(1) 最初に表示されている設問は１つのみ  (2) 設問に答えると次の設問が表示される

下記の３点を修正する。
1.switch (stepIndex) の case 1:でreturnしていたコンポーネント全体を、個別のコンポーネント Questionnaire として切り出す。
2.Content のstate として、アンケートの各設問の回答を配列answersを持たせるようにして、この配列と配列を更新する関数 setAnswersを props 経由で、Questionnaireコンポーネントまで渡すようにする。
3. 関数であったgetStepContentを、StepContentコンポーネントにする。

```Content.js
import React from "react";
import { Grid } from "@mui/material";
import Stepper from "@mui/material/Stepper";
import Step from "@mui/material/Step";
import StepLabel from "@mui/material/StepLabel";
import Button from "@mui/material/Button";
import Typography from "@mui/material/Typography";
import Radio from "@mui/material/Radio";
import RadioGroup from "@mui/material/RadioGroup";
import FormControlLabel from "@mui/material/FormControlLabel";
import FormControl from "@mui/material/FormControl";
import FormLabel from "@mui/material/FormLabel";
import Tooltip from "@mui/material/Tooltip";
import TextField from "@mui/material/TextField";
import InputLabel from "@mui/material/InputLabel";
import Select from "@mui/material/Select";

const QUESTIONS = [
  "現在、生命保険に加入されていますか？",
  "現在、入院中ですか。また、3ヶ月以内に医師の診察・検査の結果、入院・手術をすすめられたことがありますか？",
  "過去、5年以内に病気やケガで手術を受けたことまたは継続して７日以上の入院をしたことはありますか？",
];

const Questionnaire = ({ answers, setAnswers }) => {
  const handleAnswer = (answeredIndex, answer) => {
    setAnswers(answers.map((e, i) => (i === answeredIndex ? answer : e)));
  };
  return (
    <div>
      <FormControl component="fieldset">
        {answers
          .filter((_, i) => i === 0 || answers[i - 1])
          .map((answer, i) => (
            <React.Fragment key={i}>
              <FormLabel component="legend">{QUESTIONS[i]}</FormLabel>
              {answer ? (
                <Typography>{answer === "yes" ? "はい" : "いいえ"}</Typography>
              ) : (
                <RadioGroup
                  row
                  aria-label="gender"
                  name="row-radio-buttons-group"
                  onChange={(_evt, value) => {
                    handleAnswer(i, value);
                  }}
                >
                  <FormControlLabel value="yes" control={<Radio />} label="はい" />
                  <FormControlLabel value="no" control={<Radio />} label="いいえ" />
                </RadioGroup>
              )}
            </React.Fragment>
          ))}
      </FormControl>
    </div>
  );
};
function getSteps() {
  return ["お客様の情報を入力してください", "以下にお答えください", "ご相談ください"];
}

const StepContent = ({ stepIndex, questionnaireProps }) => {
  switch (stepIndex) {
    case 0:
      return (
        <>
          <div>
            <FormControl component="fieldset">
              <FormLabel component="legend">- 性別 -</FormLabel>
              <RadioGroup row aria-label="gender" name="row-radio-buttons-group">
                <FormControlLabel value="male" control={<Radio />} label="男性" />
                <FormControlLabel value="female" control={<Radio />} label="女性" />
              </RadioGroup>
            </FormControl>
          </div>
          <div>
            <FormLabel component="legend">- 生年月日 -</FormLabel>
            <FormControl sx={{ m: 1, minWidth: 120 }}>
              <InputLabel htmlFor="grouped-native-select">year</InputLabel>
              <Select native defaultValue="" id="grouped-native-select" label="Grouping">
                <option aria-label="None" value="" />
                <optgroup label="year">
                  <option value={1}>　1990</option>
                  <option value={2}>　1991</option>
                  <option value={3}>　1992</option>
                  <option value={4}>　1993</option>
                  <option value={5}>　1994</option>
                  <option value={6}>　1995</option>
                  <option value={7}>　1996</option>
                  <option value={8}>　1997</option>
                  <option value={9}>　1998</option>
                  <option value={10}>　1999</option>
                  <option value={11}>　2000</option>
                  <option value={12}>　2001</option>
                  <option value={13}>　2002</option>
                  <option value={14}>　2003</option>
                  <option value={15}>　2004</option>
                  <option value={16}>　2005</option>
                  <option value={17}>　2006</option>
                  <option value={18}>　2007</option>
                  <option value={19}>　2008</option>
                  <option value={20}>　2009</option>
                  <option value={21}>　2010</option>
                  <option value={22}>　2011</option>
                  <option value={23}>　2012</option>
                  <option value={24}>　2013</option>
                  <option value={25}>　2014</option>
                  <option value={26}>　2015</option>
                  <option value={27}>　2016</option>
                  <option value={28}>　2017</option>
                  <option value={29}>　2018</option>
                  <option value={30}>　2019</option>
                  <option value={31}>　2020</option>
                  <option value={32}>　2021</option>
                </optgroup>
              </Select>
            </FormControl>
            <FormControl sx={{ m: 1, minWidth: 120 }}>
              <InputLabel htmlFor="grouped-native-select">month</InputLabel>
              <Select native defaultValue="" id="grouped-native-select" label="Grouping">
                <option aria-label="None" value="" />
                <optgroup label="month">
                  <option value={1}> 1</option>
                  <option value={2}> 2</option>
                  <option value={3}> 3</option>
                  <option value={4}> 4</option>
                  <option value={5}> 5</option>
                  <option value={6}> 6</option>
                  <option value={7}> 7</option>
                  <option value={8}> 8</option>
                  <option value={9}> 9</option>
                  <option value={10}> 10</option>
                  <option value={11}> 11</option>
                  <option value={12}> 12</option>
                </optgroup>
              </Select>
            </FormControl>
            <FormControl sx={{ m: 1, minWidth: 120 }}>
              <InputLabel htmlFor="grouped-native-select">day</InputLabel>
              <Select native defaultValue="" id="grouped-native-select" label="Grouping">
                <option aria-label="None" value="" />
                <optgroup label="day">
                  <option value={1}> 1</option>
                  <option value={2}> 2</option>
                  <option value={3}> 3</option>
                  <option value={4}> 4</option>
                  <option value={5}> 2</option>
                  <option value={6}> 6</option>
                  <option value={7}> 7</option>
                  <option value={8}> 8</option>
                  <option value={9}> 9</option>
                  <option value={10}> 10</option>
                  <option value={11}> 11</option>
                  <option value={12}> 12</option>
                  <option value={13}> 13</option>
                  <option value={14}> 14</option>
                  <option value={15}> 15</option>
                  <option value={16}> 16</option>
                  <option value={17}> 17</option>
                  <option value={18}> 18</option>
                  <option value={19}> 19</option>
                  <option value={20}> 20</option>
                  <option value={21}> 21</option>
                  <option value={22}> 22</option>
                  <option value={23}> 23</option>
                  <option value={24}> 24</option>
                  <option value={25}> 25</option>
                  <option value={26}> 26</option>
                  <option value={27}> 27</option>
                  <option value={28}> 28</option>
                  <option value={29}> 29</option>
                  <option value={30}> 30</option>
                  <option value={31}> 31</option>
                </optgroup>
              </Select>
            </FormControl>
          </div>
        </>
      );
    case 1:
      return <Questionnaire {...questionnaireProps} />;
    case 2:
      return (
        <Grid container>
          <Grid sm={2} />
          <Grid lg={8} sm={8} spacing={10}>
            <Tooltip title="ご相談内容を記入することができます" placement="top-start" arrow>
              <TextField
                label="ご相談内容"
                fullWidth
                margin="normal"
                rows={4}
                multiline
                variant="outlined"
                placeholder="その他ご要望等あれば、ご記入ください"
              />
            </Tooltip>
          </Grid>
        </Grid>
      );
    default:
      return "Unknown stepIndex";
  }
};
function Content() {
  const [activeStep, setActiveStep] = React.useState(0);
  const [answers, setAnswers] = React.useState(Array(QUESTIONS.length).fill(null));
  const steps = getSteps();
  const handleNext = () => {
    setActiveStep((prevActiveStep) => prevActiveStep + 1);
  };
  const handleBack = () => {
    setActiveStep((prevActiveStep) => prevActiveStep - 1);
  };
  const handleReset = () => {
    setActiveStep(0);
  };
  const buttonDisabled = activeStep === 1 && answers.some((a) => !a);
  return (
    <Grid container>
      <Grid sm={2} />
      <Grid lg={8} sm={8} spacing={10}>
        <Stepper activeStep={activeStep} alternativeLabel>
          {steps.map((label) => (
            <Step key={label}>
              <StepLabel>{label}</StepLabel>
            </Step>
          ))}
        </Stepper>
        {activeStep === steps.length ? (
          <div>
            <Typography>全ステップの表示を完了</Typography>
            <Button onClick={handleReset}>リセット</Button>
          </div>
        ) : (
          <div>
            <Typography>
              <StepContent stepIndex={activeStep} questionnaireProps={{ answers, setAnswers }} />
            </Typography>
            <Button disabled={activeStep === 0} onClick={handleBack}>
              戻る
            </Button>
            <Button variant="contained" color="primary" onClick={handleNext} disabled={buttonDisabled}>
              {activeStep === steps.length - 1 ? "送信" : "次へ"}
            </Button>
          </div>
        )}
      </Grid>
    </Grid>
  );
}
export default Content;
```

##1.基本情報入力画面　
#####components / Content.js　の　case 0:　以下内の生年月日を入力する現在のソースコードを該当する数字を全て記載するのではなく動的なコードに変更する。

Array.fromを使って、その場で配列を作成する。

```sample.js
{
  Array.from(
    Array(12), 
    (_, num) => (<option key={num} value={num + 1}>{num + 1}</option>)
  )
}
```

```Content.js
import React from "react";
import { Grid } from "@mui/material";
import Stepper from "@mui/material/Stepper";
import Step from "@mui/material/Step";
import StepLabel from "@mui/material/StepLabel";
import Button from "@mui/material/Button";
import Typography from "@mui/material/Typography";
import Radio from "@mui/material/Radio";
import RadioGroup from "@mui/material/RadioGroup";
import FormControlLabel from "@mui/material/FormControlLabel";
import FormControl from "@mui/material/FormControl";
import FormLabel from "@mui/material/FormLabel";
import Tooltip from "@mui/material/Tooltip";
import TextField from "@mui/material/TextField";
import InputLabel from "@mui/material/InputLabel";
import Select from "@mui/material/Select";

const QUESTIONS = [
  "現在、生命保険に加入されていますか？",
  "現在、入院中ですか。また、3ヶ月以内に医師の診察・検査の結果、入院・手術をすすめられたことがありますか？",
  "過去、5年以内に病気やケガで手術を受けたことまたは継続して７日以上の入院をしたことはありますか？",
];

const Questionnaire = ({ answers, setAnswers }) => {
  const handleAnswer = (answeredIndex, answer) => {
    setAnswers(answers.map((e, i) => (i === answeredIndex ? answer : e)));
  };
  return (
    <div>
      <FormControl component="fieldset">
        {answers
          .filter((_, i) => i === 0 || answers[i - 1])
          .map((answer, i) => (
            <React.Fragment key={i}>
              <FormLabel component="legend">{QUESTIONS[i]}</FormLabel>
              {answer ? (
                <Typography>{answer === "yes" ? "はい" : "いいえ"}</Typography>
              ) : (
                <RadioGroup
                  row
                  aria-label="gender"
                  name="row-radio-buttons-group"
                  onChange={(_evt, value) => {
                    handleAnswer(i, value);
                  }}
                >
                  <FormControlLabel value="yes" control={<Radio />} label="はい" />
                  <FormControlLabel value="no" control={<Radio />} label="いいえ" />
                </RadioGroup>
              )}
            </React.Fragment>
          ))}
      </FormControl>
    </div>
  );
};
function getSteps() {
  return ["お客様の情報を入力してください", "以下にお答えください", "ご相談ください"];
}

const StepContent = ({ stepIndex, questionnaireProps }) => {
  switch (stepIndex) {
    case 0:
      return (
        <>
          <div>
            <FormControl component="fieldset">
              <FormLabel component="legend">- 性別 -</FormLabel>
              <RadioGroup row aria-label="gender" name="row-radio-buttons-group">
                <FormControlLabel value="male" control={<Radio />} label="男性" />
                <FormControlLabel value="female" control={<Radio />} label="女性" />
              </RadioGroup>
            </FormControl>
          </div>
          <div>
            <FormLabel component="legend">- 生年月日 -</FormLabel>
            <FormControl sx={{ m: 1, minWidth: 120 }}>
              <InputLabel htmlFor="grouped-native-select">year</InputLabel>
              <Select native defaultValue="" id="grouped-native-select" label="Grouping">
                <option aria-label="None" value="" />
                <optgroup label="year">
                  {Array.from(Array(2020), (_, num) => (
                    <option key={num} value={num + 1}>
                      {num + 1990}
                    </option>
                  ))}
                </optgroup>
              </Select>
            </FormControl>
            <FormControl sx={{ m: 1, minWidth: 120 }}>
              <InputLabel htmlFor="grouped-native-select">month</InputLabel>
              <Select native defaultValue="" id="grouped-native-select" label="Grouping">
                <option aria-label="None" value="" />
                <optgroup label="month">
                  {Array.from(Array(12), (_, num) => (
                    <option key={num} value={num + 1}>
                      {num + 1}
                    </option>
                  ))}
                </optgroup>
              </Select>
            </FormControl>
            <FormControl sx={{ m: 1, minWidth: 120 }}>
              <InputLabel htmlFor="grouped-native-select">day</InputLabel>
              <Select native defaultValue="" id="grouped-native-select" label="Grouping">
                <option aria-label="None" value="" />
                <optgroup label="day">
                  {Array.from(Array(12), (_, num) => (
                    <option key={num} value={num + 1}>
                      {num + 1}
                    </option>
                  ))}
                </optgroup>
              </Select>
            </FormControl>
          </div>
        </>
      );
    case 1:
      return <Questionnaire {...questionnaireProps} />;
    case 2:
      return (
        <Grid container>
          <Grid sm={2} />
          <Grid lg={8} sm={8} spacing={10}>
            <Tooltip title="ご相談内容を記入することができます" placement="top-start" arrow>
              <TextField
                label="ご相談内容"
                fullWidth
                margin="normal"
                rows={4}
                multiline
                variant="outlined"
                placeholder="その他ご要望等あれば、ご記入ください"
              />
            </Tooltip>
          </Grid>
        </Grid>
      );
    default:
      return "Unknown stepIndex";
  }
};
function Content() {
  const [activeStep, setActiveStep] = React.useState(0);
  const [answers, setAnswers] = React.useState(Array(QUESTIONS.length).fill(null));
  const steps = getSteps();
  const handleNext = () => {
    setActiveStep((prevActiveStep) => prevActiveStep + 1);
  };
  const handleBack = () => {
    setActiveStep((prevActiveStep) => prevActiveStep - 1);
  };
  const handleReset = () => {
    setActiveStep(0);
  };
  const buttonDisabled = activeStep === 1 && answers.some((a) => !a);
  return (
    <Grid container>
      <Grid sm={2} />
      <Grid lg={8} sm={8} spacing={10}>
        <Stepper activeStep={activeStep} alternativeLabel>
          {steps.map((label) => (
            <Step key={label}>
              <StepLabel>{label}</StepLabel>
            </Step>
          ))}
        </Stepper>
        {activeStep === steps.length ? (
          <div>
            <Typography>全ステップの表示を完了</Typography>
            <Button onClick={handleReset}>リセット</Button>
          </div>
        ) : (
          <div>
            <Typography>
              <StepContent stepIndex={activeStep} questionnaireProps={{ answers, setAnswers }} />
            </Typography>
            <Button disabled={activeStep === 0} onClick={handleBack}>
              戻る
            </Button>
            <Button variant="contained" color="primary" onClick={handleNext} disabled={buttonDisabled}>
              {activeStep === steps.length - 1 ? "送信" : "次へ"}
            </Button>
          </div>
        )}
      </Grid>
    </Grid>
  );
}
export default Content;
```

##各コンテンツのコンポーネントに応じたソースファイルを用意

```
$ touch src/components/Basic.js
$ touch src/components/Questionnaire.js
$ touch src/components/Optional.js
```

## 各コンテンツのコンポーネントに応じたソースファイルを編集する

### Content.js

```Content.js
import React from "react";
import { Grid } from "@mui/material";
import Stepper from "@mui/material/Stepper";
import Step from "@mui/material/Step";
import StepLabel from "@mui/material/StepLabel";
import Button from "@mui/material/Button";
import Typography from "@mui/material/Typography";
import Basic from "./Basic";
import Questionnaire, { QUESTIONS } from "./Questionnaire";
import Optional from "./Optional";

function getSteps() {
  return ["お客様の情報を入力して下さい", "以下にお答え下さい", "ご相談下さい", "以下の内容をご確認下さい"];
}

const StepContent = ({ stepIndex, questionnaireProps }) => {
  switch (stepIndex) {
    case 0:
      return <Basic />;
case 1:
      return <Questionnaire {...questionnaireProps} />;
    case 2:
      return <Optional />;
case 3:
      return <Basic />;
             <Questionnaire {...questionnaireProps} />;
             <Optional />;
    default:
      return "Unknown stepIndex";
  }
};
function Content() {
  const [activeStep, setActiveStep] = React.useState(0);
  const [answers, setAnswers] = React.useState(Array(QUESTIONS.length).fill(null));
  const steps = getSteps();
  const handleNext = () => {
    setActiveStep((prevActiveStep) => prevActiveStep + 1);
  };
  const handleBack = () => {
    setActiveStep((prevActiveStep) => prevActiveStep - 1);
  };
  const handleReset = () => {
    setActiveStep(0);
  };
  const buttonDisabled = activeStep === 1 && answers.some((a) => !a);
  return (
    <Grid container>
      <Grid sm={2} />
      <Grid lg={8} sm={8} spacing={10}>
        <Stepper activeStep={activeStep} alternativeLabel>
          {steps.map((label) => (
            <Step key={label}>
              <StepLabel>{label}</StepLabel>
            </Step>
          ))}
        </Stepper>
        {activeStep === steps.length ? (
          <div style={{ textAlign: "center" }}>
            <Typography>全ステップの表示を完了</Typography>
            <Button onClick={handleReset}>リセット</Button>
          </div>
        ) : (
          <div>
            <Typography>
              <StepContent stepIndex={activeStep} questionnaireProps={{ answers, setAnswers }} />
            </Typography>
            <Button disabled={activeStep === 0} onClick={handleBack}>
              戻る
            </Button>
            <Button variant="contained" color="primary" onClick={handleNext} disabled={buttonDisabled}>
              {activeStep === steps.length - 1 ? "送信" : "次へ"}
            </Button>
          </div>
        )}
      </Grid>
    </Grid>
  );
}
export default Content;
```

##### Basic.js

```Basic.js
import React from "react";
import Radio from "@mui/material/Radio";
import RadioGroup from "@mui/material/RadioGroup";
import FormControlLabel from "@mui/material/FormControlLabel";
import FormControl from "@mui/material/FormControl";
import FormLabel from "@mui/material/FormLabel";
import InputLabel from "@mui/material/InputLabel";
import Select from "@mui/material/Select";

const Basic = () => {
  return (
    <>
      <div style={{ textAlign: "center" }}>
        <FormControl component="fieldset">
          <FormLabel component="legend">- 性別 -</FormLabel>
          <RadioGroup row aria-label="gender" name="row-radio-buttons-group">
            <FormControlLabel value="male" control={<Radio />} label="男性" />
            <FormControlLabel value="female" control={<Radio />} label="女性" />
          </RadioGroup>
        </FormControl>
      </div>
      <div style={{ textAlign: "center" }}>
        <FormLabel component="legend">- 生年月日 -</FormLabel>
        <FormControl sx={{ m: 1, minWidth: 120 }}>
          <InputLabel htmlFor="grouped-native-select">year</InputLabel>
          <Select native defaultValue="" id="grouped-native-select" label="Grouping">
            <option aria-label="None" value="" />
            <optgroup label="year">
              {Array.from(Array(2020), (_, num) => (
                <option key={num} value={num + 1}>
                  {num + 1990}
                </option>
              ))}
            </optgroup>
          </Select>
        </FormControl>
        <FormControl sx={{ m: 1, minWidth: 120 }}>
          <InputLabel htmlFor="grouped-native-select">month</InputLabel>
          <Select native defaultValue="" id="grouped-native-select" label="Grouping">
            <option aria-label="None" value="" />
            <optgroup label="month">
              {Array.from(Array(12), (_, num) => (
                <option key={num} value={num + 1}>
                  {num + 1}
                </option>
              ))}
            </optgroup>
          </Select>
        </FormControl>
        <FormControl sx={{ m: 1, minWidth: 120 }}>
          <InputLabel htmlFor="grouped-native-select">day</InputLabel>
          <Select native defaultValue="" id="grouped-native-select" label="Grouping">
            <option aria-label="None" value="" />
            <optgroup label="day">
              {Array.from(Array(12), (_, num) => (
                <option key={num} value={num + 1}>
                  {num + 1}
                </option>
              ))}
            </optgroup>
          </Select>
        </FormControl>
      </div>
    </>
  );
};

export default Basic;

```

#####Questionnaire.js

複数のコンポーネントで一つのstateを共有したい場合 ➡︎ 親のコンポーネントに置く
親のコンポーネントでstateを宣言してpropsとして渡す。

```sample.js
const [answers, setAnswers] = React.useState([])

<Questionnaire answers={answers} />
```

どうやって子のコンポーネントで変数を書き換えるか　➡︎ ① stateを書き換える　　②関数をラップした関数を渡す
この方がstateの宣言とsetする関数が一つのコンポーネントに留まっているので可読性があがる。

```sample.js
const [answers, setAnswers] = React.useState([])

const handleAnswer = (answeredIndex, answer) => {
  setAnswers(answers.map((e, i) => (i === answeredIndex ? answer : e)))
}

<Questionnaire answers={answers} handleAnswer={handleAnswer} />
const Questionnaire = ({ answers, handleAnswer }) => {
    return (
        <button onClick={() => handleAnswer(answeredIndex, answer)}></button>
    )
}

```


```Questionnaire.js
import React from "react";
import Typography from "@mui/material/Typography";
import Radio from "@mui/material/Radio";
import RadioGroup from "@mui/material/RadioGroup";
import FormControlLabel from "@mui/material/FormControlLabel";
import FormControl from "@mui/material/FormControl";
import FormLabel from "@mui/material/FormLabel";

export const QUESTIONS = [
  "現在、生命保険に加入されていますか？",
  "現在、入院中ですか。また、3ヶ月以内に医師の診察・検査の結果、入院・手術をすすめられたことがありますか？",
  "過去、5年以内に病気やケガで手術を受けたことまたは継続して７日以上の入院をしたことはありますか？",
];

const Questionnaire = ({ answers, setAnswers }) => {
  const handleAnswer = (answeredIndex, answer) => {
    setAnswers(answers.map((e, i) => (i === answeredIndex ? answer : e)));
  };
  return (
    <div>
      <FormControl component="fieldset">
        {answers
          .filter((_, i) => i === 0 || answers[i - 1])
          .map((answer, i) => (
            <React.Fragment key={i}>
              <FormLabel component="legend">{QUESTIONS[i]}</FormLabel>
              {answer ? (
                <Typography>{answer === "yes" ? "はい" : "いいえ"}</Typography>
              ) : (
                <RadioGroup
                  row
                  aria-label="gender"
                  name="row-radio-buttons-group"
                  onChange={(_evt, value) => {
                    handleAnswer(i, value);
                  }}
                >
                  <FormControlLabel value="yes" control={<Radio />} label="はい" />
                  <FormControlLabel value="no" control={<Radio />} label="いいえ" />
                </RadioGroup>
              )}
            </React.Fragment>
          ))}
      </FormControl>
    </div>
  );
};

export default Questionnaire;
```

##### Optional.js

```Optional.js
import React from "react";
import { Grid } from "@mui/material";
import Tooltip from "@mui/material/Tooltip";
import TextField from "@mui/material/TextField";

const Optional = () => {
  return (
    <div>
      <Grid container>
        <Grid sm={2} />
        <Grid lg={8} sm={8} spacing={10}>
          <Tooltip title="ご相談内容を記入することができます" placement="top-start" arrow>
            <TextField
              label="ご相談内容"
              fullWidth
              margin="normal"
              rows={4}
              multiline
              variant="outlined"
              placeholder="その他ご要望等あれば、ご記入ください"
            />
          </Tooltip>
        </Grid>
      </Grid>
    </div>
  );
};
export default Optional;
```

##4. 確認画面を編集

(1) 入力した内容が表示される
(2) 『戻る』ボタンと『送信』ボタン
(3) 『送信』ボタンは動作しなくても良い


answers には質問の数だけ null が入った配列を初期値として渡す必要がある。
同様のコードはすでに contents.js　の　Questionnaire で書かれているので、contents.js　　Basic.js  Optipnal.js　を編集する。


```content.js
const [answers, setAnswers] = React.useState(Array(QUESTIONS.length).fill(null));

<Questionnaire answers={answers} setAnswers={setAnswers} /> 

    case 1:
      return <Questionnaire {...questionnaireProps} />;
```

ユーザーが React コンポーネントに与えたデータを保存するには、 state （状態）として取り扱う必要がある。 
1つの state を管理するには、 contents.js の中（上記の`sample.js）ですでに一度行なっているように、

```content.js
const [answers, setAnswers] = React.useState(Array(QUESTIONS.length).fill(null));
```

上記のように React.useState() を使って state 変数とセッター関数の組を作成する。
セッター関数でデータをセットすると次にコンポーネントが描画されるときに値が state 変数に反映される。

```content.js
<StepContent stepIndex={activeStep} questionnaireProps={{ answers, setAnswers }} />

    case 1:
      return <Questionnaire {...questionnaireProps} />;
```

Questionnaire コンポーネントに state 渡しているコードを参考に、Basic.js  Optipnal.js　を編集する。

```content.js
const [basicProfile, setBasicProfile] = React.useState({ gender: null, year: null, month: null, day: null ));
```

を Content コンポーネントの中に書いて、下記のように渡す。

```content.js
<StepContent 略 BasicProps={{ basicProfile, setBasicProfile }} />
```
Basic コンポーネント側では、下記のようにすれば、受け取れる。

```Basic.js
const Basic = ({ basicProfile, setBasicProfile }) => { 略 }

<RadioGroup 略 value={basicProfile.gender} onChange={(evt) =>
setBasicProfile((state) => {
return { ...state, gender: evt.target.value }
　　　　})
}>
```

```Basic.js
import React from "react";
import Radio from "@mui/material/Radio";
import RadioGroup from "@mui/material/RadioGroup";
import FormControlLabel from "@mui/material/FormControlLabel";
import FormControl from "@mui/material/FormControl";
import FormLabel from "@mui/material/FormLabel";
import InputLabel from "@mui/material/InputLabel";
import Select from "@mui/material/Select";

const Basic = ({ basicProfile, setBasicProfile }) => {
  return (
    <>
      <div style={{ textAlign: "center" }}>
        <FormControl component="fieldset">
          <FormLabel component="gender">- 性別 -</FormLabel>
          <RadioGroup
            row
            aria-label="gender"
            name="row-radio-buttons-group"
            value={basicProfile.gender}
            onChange={(evt) =>
              setBasicProfile((state) => {
                return { ...state, gender: evt.target.value };
              })
            }
          >
            <FormControlLabel value="male" control={<Radio />} label="男性" />
            <FormControlLabel value="female" control={<Radio />} label="女性" />
          </RadioGroup>
        </FormControl>
      </div>
      <div style={{ textAlign: "center" }}>
        <FormLabel component="legend">- 生年月日 -</FormLabel>
        <FormControl sx={{ m: 1, minWidth: 120 }}>
          <InputLabel htmlFor="grouped-native-select">year</InputLabel>
          <Select
            native
            defaultValue=""
            id="grouped-native-select"
            label="Grouping"
            value={basicProfile.year}
            onChange={(evt) =>
              setBasicProfile((state) => {
                return { ...state, year: evt.target.value };
              })
            }
          >
            <option aria-label="None" value="" />
            <optgroup label="year">
              {Array.from(Array(2020), (_, num) => (
                <option key={num} value={num + 1}>
                  {num + 1990}
                </option>
              ))}
            </optgroup>
          </Select>
        </FormControl>
        <FormControl sx={{ m: 1, minWidth: 120 }}>
          <InputLabel htmlFor="grouped-native-select">month</InputLabel>
          <Select
            native
            defaultValue=""
            id="grouped-native-select"
            label="Grouping"
            value={basicProfile.month}
            onChange={(evt) =>
              setBasicProfile((state) => {
                return { ...state, month: evt.target.value };
              })
            }
          >
            <option aria-label="None" value="" />
            <optgroup label="month">
              {Array.from(Array(12), (_, num) => (
                <option key={num} value={num + 1}>
                  {num + 1}
                </option>
              ))}
            </optgroup>
          </Select>
        </FormControl>
        <FormControl sx={{ m: 1, minWidth: 120 }}>
          <InputLabel htmlFor="grouped-native-select">day</InputLabel>
          <Select
            native
            defaultValue=""
            id="grouped-native-select"
            label="Grouping"
            value={basicProfile.day}
            onChange={(evt) =>
              setBasicProfile((state) => {
                return { ...state, day: evt.target.value };
              })
            }
          >
            <option aria-label="None" value="" />
            <optgroup label="day">
              {Array.from(Array(12), (_, num) => (
                <option key={num} value={num + 1}>
                  {num + 1}
                </option>
              ))}
            </optgroup>
          </Select>
        </FormControl>
      </div>
    </>
  );
};

export default Basic;
```
```Content.js
import React from "react";
import { Grid } from "@mui/material";
import Stepper from "@mui/material/Stepper";
import Step from "@mui/material/Step";
import StepLabel from "@mui/material/StepLabel";
import Button from "@mui/material/Button";
import Typography from "@mui/material/Typography";
import Basic from "./Basic";
import Questionnaire, { QUESTIONS } from "./Questionnaire";
import Optional from "./Optional";

function getSteps() {
  return ["お客様の情報を入力して下さい", "以下にお答え下さい", "ご相談下さい", "以下の内容をご確認下さい"];
}

const StepContent = ({ stepIndex, basicProps, questionnaireProps, optionalProps }) => {
  switch (stepIndex) {
    case 0:
      return <Basic {...basicProps} />;
    case 1:
      return <Questionnaire {...questionnaireProps} />;
    case 2:
      return <Optional {...optionalProps} />;
    case 3:
      return (
        <div style={{ textAlign: "center" }}>
          <Basic {...basicProps} />
          <Questionnaire {...questionnaireProps} />
          <Optional {...optionalProps} />
        </div>
      );
    default:
      return "Unknown stepIndex";
  }
};
function Content() {
  const [activeStep, setActiveStep] = React.useState(0);
  const [basicProfile, setBasicProfile] = React.useState({ gender: null, year: null, month: null, day: null });
  const [answers, setAnswers] = React.useState(Array(QUESTIONS.length).fill(null));
  const [optionalRequest, setOptionalRequest] = React.useState({ request: null });
  const steps = getSteps();
  const handleNext = () => {
    setActiveStep((prevActiveStep) => prevActiveStep + 1);
  };
  const handleBack = () => {
    setActiveStep((prevActiveStep) => prevActiveStep - 1);
  };
  const handleReset = () => {
    setActiveStep(0);
  };
  const buttonDisabled = activeStep === 1 && answers.some((a) => !a);
  return (
    <Grid container>
      <Grid sm={2} />
      <Grid lg={8} sm={8} spacing={10}>
        <Stepper activeStep={activeStep} alternativeLabel>
          {steps.map((label) => (
            <Step key={label}>
              <StepLabel>{label}</StepLabel>
            </Step>
          ))}
        </Stepper>
        {activeStep === steps.length ? (
          <div style={{ textAlign: "center" }}>
            <Typography>全ステップの表示を完了</Typography>
            <Button onClick={handleReset}>リセット</Button>
          </div>
        ) : (
          <div>
            <Typography>
              <StepContent
                stepIndex={activeStep}
                questionnaireProps={{ answers, setAnswers }}
                basicProps={{ basicProfile, setBasicProfile }}
                optionalProps={{ optionalRequest, setOptionalRequest }}
              />
            </Typography>
            <Button disabled={activeStep === 0} onClick={handleBack}>
              戻る
            </Button>
            <Button variant="contained" color="primary" onClick={handleNext} disabled={buttonDisabled}>
              {activeStep === steps.length - 1 ? "送信" : "次へ"}
            </Button>
          </div>
        )}
      </Grid>
    </Grid>
  );
}
export default Content;
```

``` Optional.js
import React from "react";
import { Grid } from "@mui/material";
import Tooltip from "@mui/material/Tooltip";
import TextField from "@mui/material/TextField";

const Optional = ({ optionalRequest, setOptionalRequest }) => {
  return (
    <div>
      <Grid container>
        <Grid sm={2} />
        <Grid lg={8} sm={8} spacing={10}>
          <Tooltip
            title="ご相談内容を記入することができます"
            placement="top-start"
            arrow
            value={optionalRequest.consultation}
            onChange={(evt) =>
              setOptionalRequest((state) => {
                return { ...state, consultation: evt.target.value };
              })
            }
          >
            <TextField
              label="ご相談内容"
              fullWidth
              margin="normal"
              rows={4}
              multiline
              variant="outlined"
              placeholder="その他ご要望等あれば、ご記入ください"
            />
          </Tooltip>
        </Grid>
      </Grid>
    </div>
  );
};
export default Optional;
```
```Questionnaire.js
import React from "react";
import Typography from "@mui/material/Typography";
import Radio from "@mui/material/Radio";
import RadioGroup from "@mui/material/RadioGroup";
import FormControlLabel from "@mui/material/FormControlLabel";
import FormControl from "@mui/material/FormControl";
import FormLabel from "@mui/material/FormLabel";

export const QUESTIONS = [
  "現在、生命保険に加入されていますか？",
  "現在、入院中ですか。また、3ヶ月以内に医師の診察・検査の結果、入院・手術をすすめられたことがありますか？",
  "過去、5年以内に病気やケガで手術を受けたことまたは継続して７日以上の入院をしたことはありますか？",
];

const Questionnaire = ({ answers, setAnswers }) => {
  const handleAnswer = (answeredIndex, answer) => {
    setAnswers(answers.map((e, i) => (i === answeredIndex ? answer : e)));
  };
  return (
    <div>
      <FormControl component="fieldset">
        {answers
          .filter((_, i) => i === 0 || answers[i - 1])
          .map((answer, i) => (
            <React.Fragment key={i}>
              <FormLabel component="legend">{QUESTIONS[i]}</FormLabel>
              {answer ? (
                <Typography>{answer === "yes" ? "はい" : "いいえ"}</Typography>
              ) : (
                <RadioGroup
                  row
                  aria-label="gender"
                  name="row-radio-buttons-group"
                  onChange={(_evt, value) => {
                    handleAnswer(i, value);
                  }}
                >
                  <FormControlLabel value="yes" control={<Radio />} label="はい" />
                  <FormControlLabel value="no" control={<Radio />} label="いいえ" />
                </RadioGroup>
              )}
            </React.Fragment>
          ))}
      </FormControl>
    </div>
  );
};

export default Questionnaire;

```

##確認画面で、性別・年月日・コメントが編集できるのを改善する。
（選択されたものを表示させるだけにしたい）

Basic.js のPropsを増やす。

```Basic.js
const Basic = ({ basicProfile, setBasicProfile, isConfirm }) => {
```
ここで追加した isConfirm がモードに該当します。
あとは性別のラジオを出していた箇所をの下記で isConfirm の値によってラジオか単なるテキストで表示するかを切り分ける。

```Basic.js
{isConfirm ? (
            <span>{basicProfile?.gender === "male" ? "男性" : "女性"}</span>
          ) : (
            <RadioGroup
              row
              aria-label="gender"
              name="row-radio-buttons-group"
              value={basicProfile.gender}
              onChange={(evt) =>
                setBasicProfile((state) => {
                  return { ...state, gender: evt.target.value };
                })
              }
            >
              <FormControlLabel value="male" control={<Radio />} label="男性" />
              <FormControlLabel
                value="female"
                control={<Radio />}
                label="女性"
              />
            </RadioGroup>
          )}
```

その上で Content.js の case 3 で Basic を呼び出している箇所に
下記のようにで isConfirm フラグを立てる。

``` Content.js 
<Basic isConfirm {...basicProps} />
```
年月日は下記のように書く。

```Basic.js
<InputLabel htmlFor="grouped-native-select">year</InputLabel>
          {isConfirm ? (
            <span>{basicProfile.year}</span>
          ) : (

    //省略

        )}
```

##質問の回答の画面で、質問に１度答えると回答を変更できないので、変更できるように実装する


```Questionaire.js
{answer ? (
                <Typography>{answer === "yes" ? "はい" : "いいえ"}</Typography>
              ) : (
                <RadioGroup
                  row
                  aria-label="gender"
                  name="row-radio-buttons-group"
                  onChange={(_evt, value) => {
                    handleAnswer(i, value);
                  }}
                >
                  <FormControlLabel
                    value="yes"
                    control={<Radio />}
                    label="はい"
                  />
                  <FormControlLabel
                    value="no"
                    control={<Radio />}
                    label="いいえ"
                  />
                </RadioGroup>
              )}
```

上記の anwser? の false 時の分岐のみを下記のように記載すれば実装可能

```Questionaire.js

const Questionnaire = ({ answers, setAnswers, isConfirm }) => {

//省略

{isConfirm ? (
                <Typography>{answer === "yes" ? "はい" : "いいえ"}</Typography>
              ) : (
                <RadioGroup
                  row
                  aria-label="gender"
                  name="row-radio-buttons-group"
                  onChange={(_evt, value) => {
                    handleAnswer(i, value);
                  }}
                >
                  <FormControlLabel
                    value="yes"
                    control={<Radio />}
                    label="はい"
                  />
                  <FormControlLabel
                    value="no"
                    control={<Radio />}
                    label="いいえ"
                  />
                </RadioGroup>
              )}

```
``` Content.js 
<Questionnaire isConfirm {...questionnaireProps} />
```

##完成

```Basic.js

import React from "react";
import Radio from "@mui/material/Radio";
import RadioGroup from "@mui/material/RadioGroup";
import FormControlLabel from "@mui/material/FormControlLabel";
import FormControl from "@mui/material/FormControl";
import FormLabel from "@mui/material/FormLabel";
import InputLabel from "@mui/material/InputLabel";
import Select from "@mui/material/Select";

const Basic = ({ basicProfile, setBasicProfile, isConfirm }) => {
  return (
    <>
      <div style={{ textAlign: "center" }}>
        <FormControl component="fieldset">
          <FormLabel component="gender">- 性別 -</FormLabel>
          {isConfirm ? (
            <span>{basicProfile?.gender === "male" ? "男性" : "女性"}</span>
          ) : (
            <RadioGroup
              row
              aria-label="gender"
              name="row-radio-buttons-group"
              value={basicProfile.gender}
              onChange={(evt) =>
                setBasicProfile((state) => {
                  return { ...state, gender: evt.target.value };
                })
              }
            >
              <FormControlLabel value="male" control={<Radio />} label="男性" />
              <FormControlLabel
                value="female"
                control={<Radio />}
                label="女性"
              />
            </RadioGroup>
          )}
        </FormControl>
      </div>
      <div style={{ textAlign: "center" }}>
        <FormLabel component="legend">- 生年月日 -</FormLabel>
        <FormControl sx={{ m: 1, minWidth: 120 }}>
          <InputLabel htmlFor="grouped-native-select">year</InputLabel>
          {isConfirm ? (
            <span>{basicProfile.year}</span>
          ) : (
            <Select
              native
              defaultValue=""
              id="grouped-native-select"
              label="Grouping"
              value={basicProfile.year}
              onChange={(evt) =>
                setBasicProfile((state) => {
                  return { ...state, year: evt.target.value };
                })
              }
            >
              <option aria-label="None" value="" />
              <optgroup label="year">
                {Array.from(Array(2020), (_, num) => (
                  <option key={num} value={num + 1990}>
                    {num + 1990}
                  </option>
                ))}
              </optgroup>
            </Select>
          )}
        </FormControl>
        <FormControl sx={{ m: 1, minWidth: 120 }}>
          <InputLabel htmlFor="grouped-native-select">month</InputLabel>
          {isConfirm ? (
            <span>{basicProfile.month}</span>
          ) : (
            <Select
              native
              defaultValue=""
              id="grouped-native-select"
              label="Grouping"
              value={basicProfile.month}
              onChange={(evt) =>
                setBasicProfile((state) => {
                  return { ...state, month: evt.target.value };
                })
              }
            >
              <option aria-label="None" value="" />
              <optgroup label="month">
                {Array.from(Array(12), (_, num) => (
                  <option key={num} value={num + 1}>
                    {num + 1}
                  </option>
                ))}
              </optgroup>
            </Select>
          )}
        </FormControl>
        <FormControl sx={{ m: 1, minWidth: 120 }}>
          <InputLabel htmlFor="grouped-native-select">day</InputLabel>
          {isConfirm ? (
            <span>{basicProfile.day}</span>
          ) : (
            <Select
              native
              defaultValue=""
              id="grouped-native-select"
              label="Grouping"
              value={basicProfile.day}
              onChange={(evt) =>
                setBasicProfile((state) => {
                  return { ...state, day: evt.target.value };
                })
              }
            >
              <option aria-label="None" value="" />
              <optgroup label="day">
                {Array.from(Array(31), (_, num) => (
                  <option key={num} value={num + 1}>
                    {num + 1}
                  </option>
                ))}
              </optgroup>
            </Select>
          )}
        </FormControl>
      </div>
    </>
  );
};

export default Basic;
```

```Content.js
import React from "react";
import { Grid } from "@mui/material";
import Stepper from "@mui/material/Stepper";
import Step from "@mui/material/Step";
import StepLabel from "@mui/material/StepLabel";
import Button from "@mui/material/Button";
import Typography from "@mui/material/Typography";
import Basic from "./Basic";
import Questionnaire, { QUESTIONS } from "./Questionnaire";
import Optional from "./Optional";

function getSteps() {
  return [
    "お客様の情報を入力して下さい",
    "以下にお答え下さい",
    "ご相談下さい",
    "以下の内容をご確認下さい",
  ];
}

const StepContent = ({
  stepIndex,
  basicProps,
  questionnaireProps,
  optionalProps,
}) => {
  switch (stepIndex) {
    case 0:
      return <Basic {...basicProps} />;
    case 1:
      return <Questionnaire {...questionnaireProps} />;
    case 2:
      return <Optional {...optionalProps} />;
    case 3:
      return (
        <div style={{ textAlign: "center" }}>
          <Basic isConfirm {...basicProps} />
          <Questionnaire isConfirm {...questionnaireProps} />
          <Optional isConfirm {...optionalProps} />
        </div>
      );
    default:
      return "Unknown stepIndex";
  }
};
function Content() {
  const [activeStep, setActiveStep] = React.useState(0);
  const [basicProfile, setBasicProfile] = React.useState({
    gender: null,
    year: null,
    month: null,
    day: null,
  });
  const [answers, setAnswers] = React.useState(
    Array(QUESTIONS.length).fill(null)
  );
  const [optionalRequest, setOptionalRequest] = React.useState({
    request: null,
  });
  const steps = getSteps();
  const handleNext = () => {
    setActiveStep((prevActiveStep) => prevActiveStep + 1);
  };
  const handleBack = () => {
    setActiveStep((prevActiveStep) => prevActiveStep - 1);
  };
  const handleReset = () => {
    setActiveStep(0);
  };
  const buttonDisabled = activeStep === 1 && answers.some((a) => !a);
  return (
    <Grid container>
      <Grid sm={2} />
      <Grid lg={8} sm={8} spacing={10}>
        <Stepper activeStep={activeStep} alternativeLabel>
          {steps.map((label) => (
            <Step key={label}>
              <StepLabel>{label}</StepLabel>
            </Step>
          ))}
        </Stepper>
        {activeStep === steps.length ? (
          <div style={{ textAlign: "center" }}>
            <Typography>全ステップの表示を完了</Typography>
            <Button onClick={handleReset}>リセット</Button>
          </div>
        ) : (
          <div>
            <Typography>
              <StepContent
                stepIndex={activeStep}
                questionnaireProps={{ answers, setAnswers }}
                basicProps={{ basicProfile, setBasicProfile }}
                optionalProps={{ optionalRequest, setOptionalRequest }}
              />
            </Typography>
            <Button disabled={activeStep === 0} onClick={handleBack}>
              戻る
            </Button>
            <Button
              variant="contained"
              color="primary"
              onClick={handleNext}
              disabled={buttonDisabled}
            >
              {activeStep === steps.length - 1 ? "送信" : "次へ"}
            </Button>
          </div>
        )}
      </Grid>
    </Grid>
  );
}
export default Content;
```

```Optional.js

import React from "react";
import { Grid } from "@mui/material";
import Tooltip from "@mui/material/Tooltip";
import TextField from "@mui/material/TextField";

const Optional = ({ optionalRequest, setOptionalRequest, isConfirm }) => {
  return (
    <div>
      <Grid container>
        <Grid sm={2} />
        <Grid lg={8} sm={8} spacing={10}>
          {isConfirm ? (
            <span>{optionalRequest?.consultation}</span>
          ) : (
            <Tooltip
              title="ご相談内容を記入することができます"
              placement="top-start"
              arrow
              value={optionalRequest.consultation}
              onChange={(evt) =>
                setOptionalRequest((state) => {
                  return { ...state, consultation: evt.target.value };
                })
              }
            >
              <TextField
                label="ご相談内容"
                fullWidth
                margin="normal"
                rows={4}
                multiline
                variant="outlined"
                placeholder="その他ご要望等あれば、ご記入ください"
              />
            </Tooltip>
          )}
        </Grid>
      </Grid>
    </div>
  );
};
export default Optional;
```
```Questionnaire.js
import React from "react";
import Typography from "@mui/material/Typography";
import Radio from "@mui/material/Radio";
import RadioGroup from "@mui/material/RadioGroup";
import FormControlLabel from "@mui/material/FormControlLabel";
import FormControl from "@mui/material/FormControl";
import FormLabel from "@mui/material/FormLabel";

export const QUESTIONS = [
  "現在、生命保険に加入されていますか？",
  "現在、入院中ですか。また、3ヶ月以内に医師の診察・検査の結果、入院・手術をすすめられたことがありますか？",
  "過去、5年以内に病気やケガで手術を受けたことまたは継続して７日以上の入院をしたことはありますか？",
];

const Questionnaire = ({ answers, setAnswers, isConfirm }) => {
  const handleAnswer = (answeredIndex, answer) => {
    setAnswers(answers.map((e, i) => (i === answeredIndex ? answer : e)));
  };
  return (
    <div>
      <FormControl component="fieldset">
        {answers
          .filter((_, i) => i === 0 || answers[i - 1])
          .map((answer, i) => (
            <React.Fragment key={i}>
              <FormLabel component="legend">{QUESTIONS[i]}</FormLabel>
              {isConfirm ? (
                <Typography>{answer === "yes" ? "はい" : "いいえ"}</Typography>
              ) : (
                <RadioGroup
                  row
                  aria-label="gender"
                  name="row-radio-buttons-group"
                  onChange={(_evt, value) => {
                    handleAnswer(i, value);
                  }}
                >
                  <FormControlLabel
                    value="yes"
                    control={<Radio />}
                    label="はい"
                  />
                  <FormControlLabel
                    value="no"
                    control={<Radio />}
                    label="いいえ"
                  />
                </RadioGroup>
              )}
            </React.Fragment>
          ))}
      </FormControl>
    </div>
  );
};

export default Questionnaire;
```
##参考サイト
[React 初心者が Material-UI で今どきの Web フォームを作ってみた（Stepper編）]
(https://dev.classmethod.jp/articles/react-beginners-tried-to-create-a-modern-web-form-with-material-ui-stepper/)
[ReactでRedux Formを使ってフォームの管理をしてみる]
(https://yama-itech.net/react-redux-form)
[react -router-domの導入！Material UIのボタンを使って画面遷移をしよう！]
(https://teech-lab.com/react-typescript-react-router-dom-material-ui/1817/)
[入門者でもわかるReact Routerを利用したルーティング設定の基礎]
(https://reffect.co.jp/react/react-router)
[Using Framer Motion to make page transitions in React]
(https://dev.to/sam_piggott/using-framer-motion-to-make-page-transitions-in-react-5ma)
[React Router | Learn routing in React with React-Router 6]
(https://www.youtube.com/watch?v=J4faOAn6NGA)
[こんにちはMUI！ 新しくなったMaterial UI v5]
(https://zenn.dev/h_yoshikawa0724/articles/2021-09-26-material-ui-v5#%E6%96%B0%E3%81%97%E3%81%8F%E8%BF%BD%E5%8A%A0%E3%81%95%E3%82%8C%E3%81%9F%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88)
[React 初心者が Material-UI で今どきの Web フォームを作ってみた（react-hook-form編）]
(https://dev.classmethod.jp/articles/react-beginners-tried-to-create-a-modern-web-form-with-material-ui-and-react-hook-form/)
[React hooksを基礎から理解する (useContext編)]
(https://qiita.com/seira/items/fccdf4e73c59c491558d)
[こんなに簡単なの？React Hook useContextでデータ共有]
(https://reffect.co.jp/react/react-usecontext-understanding)
[Multi-Step Form Using React and Material-UI]
(https://javascript.plainenglish.io/multi-step-form-using-react-and-material-ui-29ff7f7cf049)
[How to Create a Multi-Step Form With React, React Hooks, Bootstrap and Firebase]
(https://www.youtube.com/watch?v=kbvNrd7bBXs&t=2805s)
[React Js Multi-Step-Form Project]
(https://www.youtube.com/watch?v=78n4fn8mDjY)