Я не знаю точно, что это такое, но я столкнулся с бесчисленным количеством проблем, пытаясь выполнить простейшие обновления состояния массивов с помощью хуков.
Единственное, что я нашел для работы, это использование useReducer для выполнения одного обновления массива с отправкой обработчиков onClick. В моем текущем проекте я пытаюсь обновить состояние массива в цикле for, вложенном в функцию, которая запускается при отправке формы. Я пробовал много разных решений, и это только одна из моих попыток.
function sessionToState(session) {
let formattedArray = []
for (let i = 0; i < session.length; i++) {
formattedArray.push({ url: session[i] })
setLinksArray([...linksArray, formattedArray[i]])
}
}
// --------------------------------------------------------
return (
<div>
<form
method = "post"
onSubmit = {async e => {
e.preventDefault()
const session = await getURLs({ populate: true })
sessionToState(session)
await createGroup()
Мне было интересно, есть ли какие-то важные вещи, которые я упустил, или, может быть, несколько отличных советов и приемов о том, как работать с массивами с помощью хуков. Если нужна дополнительная информация, не стесняйтесь спрашивать. Спасибо.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


При вызове установщика состояния из вызовов вложенных функций вы должны использовать функциональная форма обновления setState. В вашем случае это будет:
setLinksArray(linksArray => [...linksArray, formattedArray[i]])
Не совсем понятно, с какими проблемами вы столкнулись, но указанное выше исправление спасет вас от неожиданного состояния linksArray.
Также это относится к любому состоянию, а не только к массивам.
С точки зрения производительности вы не должны вызывать setState каждую итерацию. Вы должны установить состояние с окончательным массивом.
const sessionToState = (session) => {
setLinksArray(
session.map(sessionItem => ({url: sessionItem}))
);
}
... или если вы хотите сохранить старые элементы, вы должны сделать это с помощью функции внутри setState ...
const sessionToState = (session) => {
setLinksArray(oldState => [
...oldState,
...session.map(sessionItem => ({url: sessionItem}))
]);
}
I was wondering if there are any big things that I am missing
TLDR: setLinksArray обновляет linksArray не в текущем рендере, а в следующем рендере.
Предположим, что переменные инициализированы следующим образом:
const [linksArray, setLinksArray] = useState([])
Подсказка в ключевом слове const, linksArray — это постоянный в пределах 1 рендера (и этот факт не изменится с let, потому что именно так работает useState).
Идея setLinksArray() состоит в том, чтобы сделать другое постоянное значение в следующем рендере.
Таким образом, цикл for будет похож на:
setLinksArray([...[], session0])
setLinksArray([...[], session1])
setLinksArray([...[], session2])
и вы получите linksArray = [session2] в следующем рендере.
Лучший способ оставаться в здравом уме — это вызывать любую функцию setState только один раз для каждого состояния при каждом рендеринге (хотя у вас может быть несколько состояний), наименьшее изменение в вашем коде:
function sessionToState(session) {
let formattedArray = []
for (let i = 0; i < session.length; i++) {
formattedArray.push({ url: session[i] })
}
setLinksArray(formattedArray)
}
Кроме того, если вам нужно выполнить побочный эффект (например, вызов API) после того, как все setState функции сделают свою работу, то есть после СЛЕДУЮЩЕГО рендеринга, вам понадобится useEffect:
useEffect(() => {
...do something with updated linksArray...
}, [linksArray])
Для более подробного ознакомления см. https://overreacted.io/react-as-a-ui-runtime
Теперь я гораздо яснее понимаю, что происходит за кулисами, что, как мне кажется, доставляет мне больше всего проблем. Спасибо за ответ.
Спасибо за ответ. В итоге я использовал useReducer для проверки некоторых вещей и понял, что, похоже, есть проблемы с редактированием состояния onSubmit. Как мне отложить отправку до тех пор, пока состояние не будет обновлено, или есть другая стратегия? Прямо сейчас я тестирую его, имея отдельную кнопку для выполнения обновления состояния, а затем, когда я нажимаю кнопку «Отправить», состояние корректно при отправке на сервер.