I'm making a program that posts train schedules. It's far from done, but I'm trying to implement an "X" button that removes trains from the list right now.
I heard React Components update every time you change their state. So why isn't the table remapping with one less train? The deletion shows up in the console, just not on the table.
function TrainPage(){
const trains =[
{name: "Thomas",
dest: "New York",
first: "05:00",
freq: 30},
{name: "Duncan",
dest: "Boston",
first: "06:00",
freq: 45}
]
const [trainList, setList] = useState(trains);
function remove(event){
console.log(event.target.id)
let train2delete = event.target.id;
trains.splice(train2delete, 1);
console.log(trains)
setList(trains);
console.log(trainList);
//but this doesn't cause the state to rerender. Why?
}
return(
<div>
<table>
<tr>
<th>Train Name</th>
<th>Destination</th>
<th>Frequency</th>
<th>Minutes Away</th>
<th>Next Arrival</th>
</tr>
{trainList.map((train, index) => (
<tr>
<td>{train.name}</td>
<td>{train.dest}</td>
<td>{train.freq}mins</td>
<td></td>
<td></td>
<td><button onClick = {remove} data-toggle='tooltip' data-placement='left' title='delete train' id = {index}>x</button></td>
</tr>
))}
</table>
CodePudding user response:
It would help if you consider the following pointers:
you need to provide the
key
prop when generating an array of JSX elements(Click here for more information).When possible avoid using indexes as values for the
key
propwhenever you update a piece of state that is an Object, you need to provide a brand new Object (Click here for more information).
function TrainPage(){ const [trainList, setList] = useState([ {name: "Thomas", dest: "New York", first: "05:00", freq: 30}, {name: "Duncan", dest: "Boston", first: "06:00", freq: 45} ]); function remove(event){ const trainName = event.target.value; // filter method results in a brand new array; setList(trainList.filter(entry => entry.name !== trainName))); } return ( <div> <table> <tr> <th>Train Name</th> <th>Destination</th> <th>Frequency</th> <th>Minutes Away</th> <th>Next Arrival</th> </tr> {/* using train.name as key value assuming that is unique. if not, please use/generate a unique string */} {trainList.map((train) => ( <tr key={train.name}> <td>{train.name}</td> <td>{train.dest}</td> <td>{train.freq}mins</td> <td></td> <td></td> <td><button onClick = {remove} data-toggle='tooltip' data-placement='left' title='delete train' value={train.name}>x</button></td> </tr> ))} </table> </div> ) }