#javascript #reactjs
Вопрос:
Мне нужно обновить данные (состояние) из другого файла (функции) (поднятие состояния). Согласно моим исследованиям, есть много способов сделать это.
Ниже приведены некоторые методы, о которых я мог бы подумать.
Однако я действительно не знаю, какой из них лучший.
function ListOFOrders() {
const [ listOrders, setListOrders ] = useState([])
//Method 1
const addingOrders = (data) => {
let temp_list = listOrders
temp_list.push(data)
setListOrders(temp_a)
}
//Method 2
const addingOrders = (data) => {
setListOrders([...listOrders, data])
}
//Method 3
const addingOrders = (data) => {
setListOrders(prevListOrders => [...prevListOrders, {...data}])
}
return (
<div>
<OrdersForm addingOrders ={addingOrders}/>
<OrdersList orders={listOrders}/>
</div>
)
}
То method 1
есть из чистого JavaScript
. Это не работает, так как страница не отображается повторно снова для обновления новых данных на экране. Я сделал console.log
в конце функции проверку, и данные действительно добавлены (обновлены). Я действительно не знаю, почему. Пожалуйста, помогите
Те method 2
и method 3
работают. Но method 2
должен вызывать listOrders
текущее состояние, в то время как другой этого не делает. Какой из них мне следует использовать ?
К вашему сведению, data
addingOrders
может быть так
{
id : 1
title : 'a_title'
}
Комментарии:
1. Если в версии 1 вы имели
setListOrders(temp_list)
в виду, что причина, по которой это не работает, двоякая: (1) вы изменили предыдущее состояние, а затем (2) вы не предоставили ссылку на массив состояний нового состояния, поэтому, поскольку React использует равенство неглубоких ссылок, а ссылка не изменилась, это приведет к повторной передаче.
Ответ №1:
Метод 1 не следует использовать (и часто не будет работать), потому что состояние никогда не должно изменяться в React. .push
изменяет состояние существующего массива.
Метод 2 обычно работает нормально, но иногда бывают случаи, когда это может быть проблематично, если listOrders
массив, над которым он закрывается, находится в устаревшем состоянии — например, если addingOrders
вызывается после вызова API, и за это время состояние могло измениться. В такой ситуации вы можете потерять элементы, которые вы ранее добавили listOrders
, в промежутке между инициализацией вызова API и его завершением.
Решением проблемы устаревшего закрытия является метод 3.используйте форму обратного вызова, первым аргументом которой будет текущее значение с сохранением состояния.
Если вы уверены addingOrders
, что не будете вызываться асинхронно, то метод 2 просто прекрасен — метод 3 не нужен.
Я вижу, что вы делаете {...data}
то же самое и в методе 3. Это будет полезно, если data
может быть изменено в другом месте — создание неглубокой копии может снизить вероятность возникновения проблем с внешней мутацией.