Доброго времени суток!
Столкнулся с ошибкой, появляющейся в консоли после удаления элемента списка из массива:
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
in Note (at Table.js:14)
Как это исправить? Понимаю, что это как-то связано с преждевременным размонтированием компонента перед завершением api запроса.
Вот код задействованных компонентов:
1. App.js, где рендерится список:
import React, { useState } from "react";
import { api } from "../utils/api";
import Table from "./Table";
function App() {
const [notes, setNotes] = useState([]);
const [isLoad, setIsLoad] = useState(false);
// Рендер записей с сервера
React.useEffect(() => {
api
.getRecords()
.then((recordsData) => {
setNotes(recordsData);
})
.catch((err) => {
console.log(err);
});
}, []);
// Добавление записи в таблицу
function addNewNote(newData) {
setIsLoad(true);
const newRecord = {
data: newData,
};
api
.putRecords(newRecord)
.then((res) => {
setNotes([...notes, res]);
})
.catch((err) => {
console.log(err);
})
.finally(() => {
setIsLoad(false);
});
}
return (
<Table
notes={notes}
setNotes={setNotes}
onAddNewNote={addNewNote}
isLoad={isLoad}
/>
);
}
export default App;
2. Table.js, в который я прокидываю полученный массив для его отображения на странице:
import React from "react";
import Note from "./Note";
import NewNote from "./NewNote";
function Table({ notes, onAddNewNote, isLoad, setNotes }) {
return (
<div className="table">
<h1 className="table__title">Таблица CRUD</h1>
<div className="table__add-area">
<NewNote handleNewNote={onAddNewNote} isLoad={isLoad} />
</div>
<div className="table__list">
{notes.map((note, i) => (
<Note
key={note._id}
dataNote={note}
notes={notes}
setNotes={setNotes}
/>
))}
</div>
</div>
);
}
export default Table;
3. Note.js - компонент, необходимый для отображения самого элемента массива:
import React, { useState } from "react";
import { api } from "../utils/api";
import NoteTextArea from "./NoteTextArea";
function Note({ dataNote, notes, setNotes }) {
const [isEdit, setIsEdit] = useState(false);
const [isLoaded, setIsLoaded] = useState(false);
const [isDeleted, setIsDeleted] = useState(false);
const [note, setNote] = useState({
name: dataNote.data.name,
age: dataNote.data.age,
email: dataNote.data.email,
phone: dataNote.data.phone,
});
function onCardClickEdit() {
setIsEdit(true);
}
function handleChange(e) {
const { name, value } = e.target;
setNote((note) => ({
...note,
[name]: value,
}));
}
// Редактирование записи
function editNote() {
setIsLoaded(true);
api
.editRecord(dataNote._id, note)
.then(() => {
setIsEdit(false);
})
.catch((err) => {
console.log(err);
})
.finally(() => {
setIsLoaded(false);
});
}
// Удаление записи из таблицы
function removeNote() {
setIsDeleted(true);
api
.deleteRecord(dataNote._id)
.then(() => {
setNotes(notes.filter((n) => n._id !== dataNote._id));
})
.catch((err) => {
console.log(err);
})
.finally(() => {
setIsDeleted(false);
});
}
return (
<NoteTextArea
dataNote={dataNote}
isEdit={isEdit}
isLoaded={isLoaded}
note={note}
onCardClickEdit={onCardClickEdit}
handleChange={handleChange}
deleteNote={removeNote}
editNote={editNote}
isDeleted={isDeleted}
/>
);
}
export default Note;