У меня есть список студентов, и я показываю их на столе. Есть две кнопки, которые указывают, по какому значению следует отсортировать список (имя или дата рождения). Когда нажимается кнопка и я сортирую список, сам список сортируется, но он не обновляется, если я не назначаю список новому списку с помощью Object.assign(newList, oldList)
, а затем обновляю его, переходя к функции состояния обновления updateList(newList)
. Вот мой код:
const students= [
{
name: "John Done",
year: 1,
birthdate: "2020-01-24",
},
{
name: "Another Done",
year: 3,
birthdate: "2002-02-20",
},
{
name: "Jack London",
year: 2,
birthdate: "1800-01-04",
},
{
name: "Text Name",
year: 3,
birthdate: "1990-02-24",
},
{
name: "Name",
year: 2,
birthdate: "2005-04-01",
},
];
ReactDOM.render(<App students={students} />, document.getElementById('root'));
function App({ students }) {
const [studentsList, setStudentsList] = useState(students);
const sortByYear = () => {
// let sortedstudents = [];
// Object.assign(sortedStudents, studentsList);
// sorteStudents.sort((a, b) => b.year - a.year);
// console.log(sorteStudents);
// setStudentsList(sortedStudents);
studentsList.sort((a,b) => b.year - a.year));
setStudentsList(studentsList);
};
const sortByDates = () => {
// let sortedStudents = [];
// Object.assign(sortedStudents, studentsList);
// sortedStudents.sort((a, b) => new Date(b.birthdate) - new Date(a.birthdate));
// console.log(sortedStudents);
// setStudentsList(sortedStudents);
studentsList.sort((a, b) => new Date(b.birthdate) - new Date(a.birthdate));
setStudentsList(studentsList);
};
return (
<div className="App">
<div>
<label>
Sort By
</label>
<button
onClick={() => sortByYear()}
>
Year
</button>
<button
onClick={() => sortByDates()}
>
Most Old
</button>
</div>
<Students students={studentsList} />
</div>
);
}
Студенческий компонент
function Students({ students }) {
return (
<div>
<table>
<thead>
<tr>
<th>Name</th>
<th>Year</th>
<th>Date of birth</th>
</tr>
</thead>
<tbody>
{students.map((student, index) => (
<tr key={index}>
<td>{student.name}</td>
<td>{student.year.toString()}</td>
<td>{student.birthdate}</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
Таким образом, хотя список студентов сортируется, состояние не обновляется, но если я назначу исходный список новому, а затем отсортирую его, а затем обновлю состояние, в котором он работает.
РАБОТАЕТ
let sortedStudents = [];
Object.assign(sortedStudents, studentsList);
sortedStudents.sort((a, b) => new Date(b.birthdate) - new Date(a.birthdate));
//console.log(sortedStudents);
setStudentsList(sortedStudents)
НЕ РАБОТАЕТ
studentsList.sort((a, b) => new Date(b.birthdate) - new Date(a.birthdate));
setStudentsList(studentsList);
Итак, вопрос в том, почему мне нужно назначать свой studentsList
новому массиву, в частности, используя Object.assign()
, чтобы setStudentsList()
обновлял состояние компонента? Я только начал изучать React, поэтому меня действительно сбивает с толку то, как на самом деле работают эти состояния.
Похожие сообщения, которые я нашел
studentList
имеет ссылочное равенство с обновленнымstudentList
, и React не обнаружит, что ему нужно повторно отрендерить. - person Brian Thompson   schedule 30.12.2020sort
изменяет состояние, аassign
- нет. - person Dennis Vash   schedule 30.12.2020Object.assign
здесь. Вам нуженconst sortedStudents = studentsList.slice();
(или любая альтернатива, копирующая массив). - person Bergi   schedule 30.12.2020