#javascript #reactjs #react-hooks
Вопрос:
Я новичок в react и создаю приложение react , в этом приложении продукты питания можно перетаскивать в список заказов с помощью react dnd , проблема , с которой я сталкиваюсь, заключается в том, что я не могу получить обновленную переменную списка заказов ни в одной функции за пределами эффекта использования,
в списке addFoodToOrderList , useEffect ,я печатаю ту же переменную списка заказов , но в списке addFoodToOrderList вывод пуст , я знаю, что useState является асинхронной функцией, но при добавлении 3-го элемента в список заказов он должен показывать по крайней мере первые 2 элемента, но в качестве вывода он выдает пустой массив(0), регистр для useEffect отличается
код :
export default function FoodCardContainer() {
const [liked,setLiked] = useState("")
function handleLike(e) {
setLiked(prevNotes => {
return [...prevNotes,e];
});
}
const [orderList, setOrderList] = useState([]);
const [{ isOver }, drop] = useDrop(() => ({
accept: "div",
drop: (item) => {
addFoodToOrderList(item.id)},
collect: (monitor) => ({
isOver: !!monitor.isOver(),
}),
}));
const addFoodToOrderList = (id) => {
const orderItem = fooditems.filter((f) => id === f._id)
setOrderList((preorderLists) => {return [...preorderLists,orderItem[0]]});
console.log("this one outside useEffect",orderList)
};
useEffect(() => {
console.log("this one inside useEffect",orderList)
},[orderList])
моя консоль:
Комментарии:
1. Я подозреваю
useDrop
, что он запоминает функцию, которую он выполняет, как закрытие с переменнойaddFoodToOrderList
and initialorderList
. ВсякийFoodCard
раз, когда выполняется повторная отрисовка, переданная функцияuseDrop
может быть проигнорирована и по-прежнему удерживаться при первом вызове при начальной отрисовке.
Ответ №1:
Похоже, что переданная функция drop
была сохранена в памяти и никогда не обновлялась. В документах это упоминается в качестве параметров для useDrop
:
удаляет массив зависимостей, используемый для запоминания. Это ведет себя как встроенный крючок useMemoReact. Значение по умолчанию-пустой массив для спецификации функции и массив, содержащий спецификацию для спецификации объекта.
Поскольку вы предоставили спецификацию функции, по умолчанию она была пуста как массив в качестве deps.
Поэтому вы должны указать deps.
const [{
isOver
}, drop] = useDrop(() => ({
accept: "div",
drop: (item) => {
addFoodToOrderList(item.id)
},
collect: (monitor) => ({
isOver: !!monitor.isOver(),
}),
}), [addFoodToOrderList]);
Комментарии:
1. Хорошая находка, возможно, включает фрагмент кода, показывающий, как ее решить? Мне немного странно, что этот крючок по умолчанию использует пустой массив вместо того, чтобы не определять массив зависимостей и повторно фиксировать закрытие при каждом рендеринге. По умолчанию это может быть менее эффективным, но приведет к меньшей путанице в запоминании, как в этом вопросе.
2. @MarcBaumbach может быть да. Я добавил пример. Они говорят: «Значение по умолчанию-пустой массив для спецификации функции и массив, содержащий спецификацию для спецификации объекта».