今回の狙い
前回の内容で表示させていたポップアップ画面が寂しい。。。
という事で、ポップアップ画面を作ってみたいと思います。
具体的な目標として、以下のポップアップを、
以下のポップアップ画面に変える事を目標とします。
Reactのプログラム
以下のプログラムを用意します。
フォルダ構成
└── src
├── index.js (初期起動プログラム)
└── App.js (画面へ表示される本体)
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
app.js
import { useState } from 'react';
import { Grid, Select, MenuItem, InputLabel, TextField, Button, Dialog, DialogTitle, DialogContent, DialogActions } from '@mui/material';
import { styled } from '@mui/material/styles';
// 正常の時のダイアログの見出しスタイル
const SuccessDialogTitle = styled(DialogTitle)(({ theme }) => ({
backgroundColor: theme.palette.primary.main,
color: theme.palette.primary.contrastText,
}));
// エラーの時のダイアログの見出しスタイル
const ErrorDialogTitle = styled(DialogTitle)(({ theme }) => ({
backgroundColor: theme.palette.error.main,
color: theme.palette.error.contrastText,
}));
export default function App() {
// 初期値設定
const [showDialog, setShowDialog] = useState(false);
const [form, setForm] = useState({ mode: 'CMPL', msg: '正常を選択しています' });
const [dialogMessage, setDialogMessage] = useState('');
const [isSuccess, setIsSuccess] = useState(false);
// 変更された入力値を適用する処理
const handleForm = (e) => {
setForm({
...form,
[e.target.name]: e.target.value,
});
};
// ポップアップ画面の起動処理
const handleOpenDialog = (message, success) => {
setDialogMessage(message);
setIsSuccess(success);
setShowDialog(true);
};
// ポップアップ画面の終了処理
const handleCloseDialog = () => {
setShowDialog(false);
};
// 実行ボタン処理
const onsubmit = () => {
console.log(`a:${form.mode}`);
if (form.mode === "ER") {
handleOpenDialog(form.msg, false);
} else {
handleOpenDialog(form.msg, true);
}
};
// 画面定義
return (
<div className="App">
<form>
<Grid container spacing={2}>
<Grid size={{xs:12}}>
<InputLabel id="mode">モード選択</InputLabel>
<Select labelid="mode" name="mode" value={form.mode} onChange={handleForm}>
<MenuItem value="ER">エラー</MenuItem>
<MenuItem value="CMPL">正常</MenuItem>
</Select>
</Grid>
<Grid size={{xs:12}}>
<TextField id="msg" name="msg" label="ポップアップメッセージ" value={form.msg} onChange={handleForm} />
</Grid>
<Grid size={{xs:12}}>
<Button variant="contained" color="primary" onClick={onsubmit}>実行</Button>
</Grid>
</Grid>
</form>
<Dialog open={showDialog} onClose={handleCloseDialog}>
{isSuccess ? (
<SuccessDialogTitle>Infomation</SuccessDialogTitle>
) : (
<ErrorDialogTitle>Error</ErrorDialogTitle>
)}
<DialogContent>
<p>{dialogMessage}</p>
</DialogContent>
<DialogActions>
<Button onClick={handleCloseDialog} color="primary">
閉じる
</Button>
</DialogActions>
</Dialog>
</div>
);
}
可読性を考える
ある程度、動作が確立したら、少しメンテナンスも考えて可読性を上げたい。
では、どのように改造して可読性を向上させるか? ここで少し問題が…
<可読性> ・・・ プログラムを見易く、解り易くがする事
そこで、Aiに可読性の良いプログラムを提案させると、
実行ボタン処理.js
const onsubmit = () => {
console.log(`a:${form.mode}`);
if (form.mode === "ER") {
handleOpenDialog(form.msg, false);
} else {
handleOpenDialog(form.msg, true);
}
};
この部分が、以下のように変わります。
実行ボタン処理.js
const onsubmit = () => {
console.log(`a:${form.mode}`);
handleOpenDialog(form.msg, form.mode !== "ER");
};
確かに、スマートになって見易くなった…と。ただ、「可読性」を考えると…??
私のようなジジィ世代は、if文があった方が見易い(可読性が高い)となる訳です。
と、、、諸説ありますが(ほんとに多い…)、このままですと、少々メンテナンス性が低いので、ジジィ的な可読性の向上を目指します。
フォルダ構成
└── src /
├── components /
| ├── Form.js
| └── AlertDialog.js
├── pages /
| └── App.js
└── index.js
Form.js
import React from 'react';
import { Grid, Select, MenuItem, InputLabel, TextField, Button } from '@mui/material';
export default function Form({ form, handleForm, onsubmit }) {
return (
<form>
<Grid container spacing={2}>
<Grid size={{xs:12}}>
<InputLabel id="mode">モード選択</InputLabel>
<Select labelid="mode" name="mode" value={form.mode} onChange={handleForm}>
<MenuItem value="ER">エラー</MenuItem>
<MenuItem value="CMPL">正常</MenuItem>
</Select>
</Grid>
<Grid size={{xs:12}}>
<TextField id="msg" name="msg" label="ポップアップメッセージ" value={form.msg} onChange={handleForm} />
</Grid>
<Grid size={{xs:12}}>
<Button variant="contained" color="primary" onClick={onsubmit}>実行</Button>
</Grid>
</Grid>
</form>
);
}
AlertDialog.js
import React from 'react';
import { Button, Dialog, DialogTitle, DialogContent, DialogActions } from '@mui/material';
import { styled } from '@mui/material/styles';
// 正常の時のダイアログの見出しスタイル
const SuccessDialogTitle = styled(DialogTitle)(({ theme }) => ({
backgroundColor: theme.palette.primary.main,
color: theme.palette.primary.contrastText,
}));
// エラーの時のダイアログの見出しスタイル
const ErrorDialogTitle = styled(DialogTitle)(({ theme }) => ({
backgroundColor: theme.palette.error.main,
color: theme.palette.error.contrastText,
}));
// ダイアログの処理(オープン処理、クローズ処理、メッセージ、エラー判定)
export default function AlertDialog({ open, onClose, message, isSuccess }) {
return (
<Dialog open={open} onClose={onClose}>
{isSuccess ? (
<SuccessDialogTitle>Infomation</SuccessDialogTitle>
) : (
<ErrorDialogTitle>Error</ErrorDialogTitle>
)}
<DialogContent>
<p>{message}</p>
</DialogContent>
<DialogActions>
<Button onClick={onClose} color="primary">
閉じる
</Button>
</DialogActions>
</Dialog>
);
}
App.js
import React, { useState } from 'react';
import Form from '../components/Form';
import AlertDialog from '../components/AlertDialog';
export default function App() {
const [showDialog, setShowDialog] = useState(false);
const [form, setForm] = useState({ mode: 'CMPL', msg: '正常を選択しています' });
const [dialogMessage, setDialogMessage] = useState('');
const [isSuccess, setIsSuccess] = useState(false);
// 変更された入力値を適用する処理
const handleForm = (e) => {
setForm({
...form,
[e.target.name]: e.target.value,
});
};
// ポップアップ画面の起動処理
const handleOpenDialog = (message, success) => {
setDialogMessage(message);
setIsSuccess(success);
setShowDialog(true);
};
// ポップアップ画面の終了処理
const handleCloseDialog = () => {
setShowDialog(false);
};
// 実行ボタン処理
const onsubmit = () => {
console.log(`a:${form.mode}`);
handleOpenDialog(form.msg, form.mode !== "ER");
};
// 画面定義
return (
<div className="App">
<Form form={form} handleForm={handleForm} onsubmit={onsubmit} />
<AlertDialog open={showDialog} onClose={handleCloseDialog} message={dialogMessage} isSuccess={isSuccess} />
</div>
);
}
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './pages/App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
フォームを2つに分けて、イベントも切り出して、かなりスッキリした感じです。
以上、御疲れ様でした~。