import { useEffect, useState } from 'react'; interface TestInterface { id: number; field1: string; field2: string; } let defs = [ {key:'-', value:'-'}, {key:'001', value:'A'}, {key:'002', value:'B'}, {key:'003', value:'C'}, {key:'004', value:'D'}, {key:'005', value:'E'}, {key:'006', value:'F'}, {key:'007', value:'G'} ]; let columns = new Map(); columns.set('001', ['dataA-1', 'dataA-2', 'dataA-3']); columns.set('002', ['dataB-1', 'dataB-2', 'dataB-3']); columns.set('003', ['dataC-1', 'dataC-2', 'dataC-3']); columns.set('004', ['dataD-1', 'dataD-2', 'dataD-3']); columns.set('005', ['dataE-1', 'dataE-2', 'dataE-3']); columns.set('006', ['dataF-1', 'dataF-2', 'dataF-3']); columns.set('007', ['dataG-1', 'dataG-2', 'dataG-3']); const CustomTable = () => { const [users, setUsers] = useState<TestInterface[]>([]); const[count, setCount] = useState<number>(1); useEffect(() => { }, [users]); const addRow = () => { const user : TestInterface = { id: count, field1: '-', field2: '-' }; setCount(count+1); setUsers([...users, user]); } const deleteRow = (i : number) => { setUsers(users.filter((user) => (user.id !== i))); } const upRow = (id: number, index:number) => { if (index === 0 || users.length < 2) { return; } for (let j = 1; j < users.length; j++) { const user2 : TestInterface = users[j]; if (user2.id === id) { setUsers((prevState) => { // オブジェクトをコピーしないと再描画されない。 let tempUsers : TestInterface[] = [...prevState]; const moving = tempUsers.splice(j, 1)[0]; tempUsers.splice(j - 1, 0, moving); return tempUsers; }); break; } } } const downRow = (id: number, index:number) => { if (index === users.length -1 || users.length < 2) { return; } for (let j = 0; j < users.length-1; j++) { const user2 : TestInterface = users[j]; if (user2.id === id) { setUsers((prevState) => { // オブジェクトをコピーしないと再描画されない。 let tempUsers : TestInterface[] = [...prevState]; const moving = tempUsers.splice(j, 1)[0]; tempUsers.splice(j + 1, 0, moving); return tempUsers; }); break; } } } const onChange1 = (id: number, e: any) => { setUsers((prevState) => { // オブジェクトをコピーしないと再描画されない。 let tempUsers : TestInterface[] = [...prevState]; let test1: TestInterface = tempUsers.filter((elem) => elem.id === id)[0]; test1.field1 = e.target.value; return tempUsers; }); } const onChange2 = (id: number, e: any) => { setUsers((prevState) => { // オブジェクトをコピーしないと再描画されない。 let tempUsers : TestInterface[] = [...prevState]; let test1: TestInterface = tempUsers.filter((elem) => elem.id === id)[0]; test1.field2 = e.target.value; return tempUsers; }); } const Field2 = (props: any) => { if (props.user.field1 === '-') { return ( <select name="field2" onChange={(e) => onChange2(props.user.id, e)} value={props.user.field2}> <option value="-">-</option> </select> ); } else { const options: string[] = columns.get(props.user.field1); return ( <select name="field2" onChange={(e) => onChange2(props.user.id, e)} value={props.user.field2}> {options.map((value: string, index: number) => ( <option value={value} key={index}>{value}</option> ))} </select> ); } } const setData = (e: any) => { if (e.target.value === '1') { const _users : TestInterface[] = [ { id: 1, field1: '001', field2: 'dataA-1' }, { id: 2, field1: '-', field2: '-' }, { id: 3, field1: '002', field2: 'dataB-1' }, ]; setCount(_users.length + 1); setUsers(_users); } else if (e.target.value === '2') { const _users : TestInterface[] = [ { id: 1, field1: '003', field2: 'dataC-1' }, { id: 2, field1: '-', field2: '-' }, { id: 3, field1: '004', field2: 'dataD-1' }, { id: 4, field1: '005', field2: 'dataE-3' }, ]; setCount(_users.length + 1); setUsers(_users); } else if (e.target.value === '3') { const _users : TestInterface[] = [ { id: 1, field1: '003', field2: 'dataC-1' }, { id: 2, field1: '-', field2: '-' }, { id: 3, field1: '004', field2: 'dataD-1' }, { id: 4, field1: '004', field2: 'dataD-2' }, { id: 5, field1: '005', field2: 'dataE-3' }, ]; setCount(_users.length + 1); setUsers(_users); } } return ( <div> データのロード <select onClick={(e) => setData(e)}> <option value="-">-</option> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> </select> <table> <thead> <tr> <th>ID</th> <th>フィールド1</th> <th>フィールド2</th> <th></th> </tr> </thead> <tbody> {users.map((user: TestInterface, index: number) => ( <tr key={user.id} > <td>{user.id}</td> <td> <select name="field1" onChange={(e) => onChange1(user.id, e)} value={user.field1}> {defs.map((item: any, index: number) => ( <option value={item.key} key={index}>{item.value}</option> ))} </select> </td> <td> <Field2 user={user} /> </td> <td> <button onClick={() => upRow(user.id, index)}>上へ</button> <button onClick={() => downRow(user.id, index)}>下へ</button> <button onClick={() => deleteRow(user.id)}>削除</button> </td> </tr> ))} </tbody> </table> <button onClick={() => addRow()}>追加</button> </div> ); }; export default CustomTable;