Возможно, не зная этого, вы подняли состояние : в основном, вместо того, чтобы иметь состояние в компоненте Child
, вы сохраняете его в Parent
.
Это используется шаблон, и в этом нет ничего плохого: вы просто пропускаете функцию дескриптора, которая позволяет дочерним элементам обновлять состояние Parent
: для этого вам нужно реализовать компонент handleChange
на Parent
, а затем передать это как подпорка для каждого Child
.
Взгляните на этот пример кода:
const Parent = () => {
const [categories, setCategories] = useState([]);
useEffect(() => {
// Making your AXIOS request.
}, []);
const handleChange = (index, property, value) => {
const newCategories = [...categories];
newCategories[index][property] = value;
setCategories(newCategories);
}
return categories.map((c, i) => {
return (
<Child
key={i}
categoryIndex={i}
firstName={c.firstName}
lastName={c.lastName}
handleChange={handleChange} />
);
});
}
const Child = (props) => {
...
const onInputChange = (e) => {
props.handleChange(props.categoryIndex, e.target.name, e.target.value);
}
return (
...
<input name={'firstName'} value={props.firstName} onChange={onInputChange} />
<input name={'lastName'} value={props.lastName} onChange={onInputChange} />
);
}
Несколько вещей, которые вы можете не знать:
- Используя атрибут
name
для input
, вы можете использовать только одну функцию-обработчик для всех элементов input
. Внутри функции, в данном случае onInputChange
, вы можете получить эту информацию, используя e.target.name
; - Обратите внимание, что я добавил пустой массив зависимостей в ваш
useEffect
: без него, useEffect
побежал бы на КАЖДОЙ рендер. Я не думаю, что это то, что вы хотели бы иметь.
Вместо этого я хотел, чтобы вы хотели выполнить запрос только тогда, когда компонент был смонтирован, и это достижимо с n зависимостями пустых массивов;