はじめに
こんにちは!
私は,学生開発チーム「Nineteen」(@nineteen_team)でシフト作成アプリを開発に携わっているのですが,開発するにあたって遭遇した問題点,解決策を,備忘録も兼ねて今日から書いていきたいと思います。
Nineteenで開発しているシフト作成アプリに関してはまたの機会に詳しく記事にしようと思います。
私自身プログラミング初学者のため,誤った表現をしてしまうなど,全体的にわかりづらい記事になってしまうことを予めご承知おきください。
問題点
ReactとMaterialUIで作成した以下のような画面で,ドロップダウンメニューからアイテムを選択しても反映されない問題に遭遇しました。
このメニューからアイテムを選択すると,setStateで「rows」というstateの「position」が変更されるようになっています。stateは以下のようになっています。
//positon 0が"未設定",1が"厨房",2が"ホール" const [rows, setRows] = React.useState([ {id:0,name:"0太郎",position:1,color:'#00ff00'}, {id:1,name:"1太郎",position:2,color:'#00ff00'}, ]);
また,コンポーネントは以下のようになっています。
<TableContainer component={Paper} sx={{ minWidth: 550 }}> <Table aria-label="simple table"> <TableHead> <TableRow> <TableCell align="left"><b>名前</b></TableCell> <TableCell align="left"><b>ポジション名</b></TableCell> <TableCell align="left"><b>色</b></TableCell> </TableRow> </TableHead> <TableBody> {rows.map((row, index) => ( <TableRow key={row.id} sx={{ '&:last-child td, &:last-child th': { border: 0 } }} > <TableCell component="th" scope="row" align="left"> <font size="5">{row.name}</font> </TableCell> <TableCell align="left"> <FormControl variant="standard" sx={{ mt: 1, mb: 1, minWidth: 120 }}> <InputLabel id="demo-simple-select-standard-label"></InputLabel> <Select labelId="demo-simple-select-standard-label" id="demo-simple-select-standard" value={row.position} onChange={(event) => { let newState = rows; newState[index].position = event.target.value; setRows(newState); }} label="ポジション" > {pos.map((po) => { return ( <MenuItem value={po.id} key={po.id}>{po.name}</MenuItem> ) })} </Select> </FormControl> </TableCell> <TableCell align="left"><Typography variant="h4" style={{ color: row.color }}>■</Typography></TableCell> </TableRow> ))} </TableBody> </Table> </TableContainer>
解決策
2時間ほど格闘した結果,以下のように修正することで解決しました。
修正前
<Select labelId="demo-simple-select-standard-label" id="demo-simple-select-standard" value={row.position} //変更したところ onChange={(event) => { let newState = rows; console.log(newState[index]); newState[index].position = event.target.value; setRows(newState); } label="ポジション" >
修正後
<Select labelId="demo-simple-select-standard-label" id="demo-simple-select-standard" defaultValue={row.position} //変更したところ onChange={(event) => { let newState = rows; console.log(newState[index]); newState[index].position = event.target.value; setRows(newState); } label="ポジション" >
Selectコンポーネントの「value」というpropsを「defaultValue」に書き換えることにより解決しました。
このようにしっかりと動作するようになりました!