#reactjs #firebase #render #react-hooks
#reactjs #firebase #визуализация #реагирующие хуки
Вопрос:
У меня есть firebase
проект с a firestore
database
document
, который выглядит следующим образом.
document-id =>
item1 => {detail: "value", title: "value", image: "value}
item2 => {detail: "value", title: "value", image: "value}
...
Мой React component
рендеринг выглядит примерно так:
const [data, setData] = useState({});
useEffect(() => {
firebase.getDocument("path-to-document").then(section => {
if (section) {
setPanels(section.data());
}
});
}, []);
const handleChange = (id, data) => {
const payload = data;
payload[id] = { ...panels[id], ...data };
setData(payload);
}
return (<div>
{Object.keys(data).map((key) => <Card
data={data[key]}
onChange={handleChange} />)}
</div>);
Я удалил из этого дополнительный код, но Card
компонент simple устанавливает макет для отдельных объектов. При изменении он вызывает handleChange
функцию правильно, и data State
она правильно обновляется до новых значений (вызов console.log(data)
после setData
вызова метода показывает это). Однако component
это не reRender
происходит с новыми значениями для data
.
Есть ли какой-нибудь способ принудительно выполнить повторный запуск компонента? Я нашел в другом месте в Интернете, что React
«отключается» от повторного запроса, если setData вызывается с теми же данными, что и в настоящее время, т.Е. Никаких фактических изменений не будет сделано.
Или, наоборот, есть ли другой способ справиться с этим взаимодействием и позволить Card
компоненту обрабатывать сохранение данных?
Спасибо.
Ответ №1:
Попробуйте установить копию вашей полезной нагрузки: {...payload}
:
const handleChange = (id, data) => {
const payload = data;
payload[id] = { ...panels[id], ...data };
setData({...payload});
}
Поскольку вы не меняете состояние, ваше приложение не реагирует и не выполняет повторные запросы.
Ознакомьтесь с функциональными обновлениями в документах React.
const handleChange = (id, data) => {
const payload = data;
payload[id] = { ...panels[id], ...data };
setData(prevPayload => {
console.log(prevPayload === payload) // true
return payload // No Re-Render
// console.log(prevPayload === { ... payload }) // false
// return { ... payload } // Re-render
);
}
Изучите этот пример в codesandbox.
Комментарии:
1. Это правильно, но вы должны объяснить, почему это так.