Потеря согласованности между react-компонентом и его состоянием в родителе
Разрабатываю свое первое приложение на react-e, текущая версия которого здесь, а гит здесь.
В основе лежит App компонент-функция с состоянием
const [formValues, setFormValues] = React.useState({
drugs: [{}],
numOfForms: 1
});
, внутри которого рендерятся Form компонент-функции в количестве, зависимом от numOfForms.
Стокнулся с проблемой после реализации кнопки удаления формы:
function handleDeleteForm(index){
let form = formValues.drugs;
form.splice(index, 1);
setFormValues(formValues => ({
drugs: form,
numOfForms: (formValues.numOfForms -= 1)
}));
}
Здесь я по индексу удаляю объект в массиве форм в состоянии, а затем заново выполняется рендеринг меньшего количества форм. Проблема: React просто не выполняет рендеринг "последней" из форм, а не той, которую я удалил состоянии. В результате состояние в App расходится с тем, что лицезреет пользователь, хотя, как мне казалось, такого быть не может.
Скриншоты:
1) Изначальная картина

2) После удаления первой (!!!) формы

Как видите, на экране остается та, которую удалил.
Хотя, поверьте мне, в состоянии App хранятся сейчас единственные данные второй формы (проверял console.log() и отработкой скрипта генерации).
Я могу понять: не предусматриваю особенностей реакта или где-то наговнокодил. Подскажите, пожалуйста.
Что пробовал:
- Прокидывать values (по нему идет построение всех элементов) в Form
<Form onChange={handleFormChange}
onClickDelete={handleDeleteForm}
index={i}
numOfForms={formValues.numOfForms}
values = {formValues.drugs[i]}
/>
Не принесло никакого результата.
- Прокидывать новую пропертю valuesSave таким же образом: упешно прокидываетя, но не смог правильно выполнить синхронизацию.
Меня преследует чувство, что решение проще и я его не вижу в силу своей неопытности. Заранее спасибо!
Ответы (1 шт):
Меня преследует чувство, что решение проще и я его не вижу в силу своей неопытности. Не без помощи ребят с опытом проблему решил, и, как оказалось, чувство, не подвело.
Проблема крылась в нарушение азов: присваивал компонентам-формам "уникальные" значения key, которые были вовсе не уникальные -- как только происходило удаление одной из форм, key сдвигалось и уже отрисовало не то.
Так, теперь в состоянии в массиве объектов форм хранился так же реально уникальный индекс, который генерировал как Date.now(). Передавал соответственно теперь уже реально уникальный ключ:
<Form onChange={handleFormChange}
onClickDelete={handleDeleteForm}
keyValue={formValues.drugs[i].id}
key={formValues.drugs[i].id}
numOfForms={formValues.numOfForms}
values = {formValues.drugs[i]}
/>
Ну и во всех функциях, параметром в которых был ключ, выполняю поиск индекса данной формы в массиве:
let arrIndex = 0;
for (arrIndex; arrIndex < formValues.numOfForms; arrIndex++){
if (formValues.drugs[arrIndex].id === key){
break;
}
}
Собственно, все.