#javascript #reactjs #next.js
Вопрос:
Состояние массива не изменяется при вызове метода изменения состояния :
const [arrayOfDocuments, setArrayOfDocuments] = useState([]);
я пытался : setArrayOfDocuments(...[]); or setArrayOfDocuments([]);
где я использую свой метод :
const pushToArrayOfDocuments = (obj) => {
const arr = arrayOfDocuments;
if (obj.filename amp;amp; obj.file amp;amp; obj.expiredate amp;amp; obj.doctype) {
const index = arr.map((e) => e.filename).indexOf(obj.filename);
if (index !== -1) {
arr[index] = obj;
} else {
arr.push(obj);
}
setArrayOfDocuments(arr);
}
};
Может быть, проблема в том, чтобы подтолкнуть? и я должен это сделать setArrayOfDocuments(...arr); or setArrayOfDocuments(prev => [...prev,...arr])
, но если я сделаю это, я думаю, что это будет продолжаться бесконечно, когда я перейду pushToArrayOfDocuments
к подкомпонентам.
Подобный этому :
OperatorDocument
key={`Durc${count}`}
title="Durc"
description="Descrizione Durc"
setDocument={pushToArrayOfDocuments}
document={getObjectByName('Durc')}
filedocname="Durc"
/>
Редактировать :
делаем вот так : setArrayOfDocuments([...arr]);
я получаю Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.
Любая помощь будет признательна.
Комментарии:
1.
arr
будет по-прежнему равноarr
, поэтому изменение состояния не будет вызвано. Ты мог бы просто сделать … >setArrayOfDocuments([...arr]);
2. @Keith таким образом, это приведет к бесконечному рендерингу любого решения ?
3.
so i guess it will go in infinte rendering as i'm passing pushToArrayOfDocuments
В этом -то и проблема. Почему эта измененная ссылка вызывает бесконечный рендеринг? Вот в чем заключается настоящая проблема — покажитеuseEffect
OperatorDocument
, что никогда не используйтеpush
(илиsplice
) или что-либо, что изменяет что-либо в React.4. Поместите старый массив в новую переменную, т. Е.
updatedArray
Добавьте в нее изменения , установите состояние для этого массива.
Ответ №1:
Во-первых, вы никогда не должны напрямую изменять useState
состояние, использовать их как неизменяемые сущности. Если вы хотите использовать его в качестве начального значения, клонируйте его перед:
const arr = [...arrayOfDocuments]
// or
const arr = arrayOfDocuments.slice()
Во-вторых, вы передаете один и тот же массив состояний сеттеру, тогда состояние не будет обновляться. Клонирование государства решит этот второй вопрос.
Наконец, лучший способ построить новое состояние из старого значения-это использовать функцию:
setState(oldValue => (/* construct new state based on old value */))
это позволит избежать использования значения, которое не является актуальным.
В конце концов, у вас будет:
const pushToArrayOfDocuments = (obj) => {
if (obj.filename amp;amp; obj.file amp;amp; obj.expiredate amp;amp; obj.doctype) {
setArrayOfDocuments(oldArr => {
const arr = oldArr.slice();
const index = arr.map((e) => e.filename).indexOf(obj.filename);
if (index !== -1) {
arr[index] = obj;
} else {
arr.push(obj);
}
return arr;
}
)
}
};
Ответ №2:
Вам нужно клонировать свой массив, прежде чем добавлять его в состояние.
const arr = arrayOfDocuments.slice();
Полный фрагмент:
const pushToArrayOfDocuments = (obj) => {
if (obj.filename amp;amp; obj.file amp;amp; obj.expiredate amp;amp; obj.doctype) {
const arr = arrayOfDocuments.slice();
const index = arr.findIndex(({ filename }) => filename === obj.filename);
if (index > -1) {
arr[index] = obj;
} else {
arr.push(obj);
}
setArrayOfDocuments(arr);
}
};
Ответ №3:
Я добавляю аналогичную проблему, и я решил ее с помощью
вместо
const arr = Массив документов
попробуйте распространить исходный массив
const arr = […массив документов]