У меня есть простой компонент React, который поддерживает массив людей в состоянии с помощью хука useState
. Компонент позволяет добавлять новых людей с помощью простого компонента дочерней формы. Он не функционирует должным образом, поскольку массив состояний people
кажется сбрасывается / возвращается к своему начальному значению между добавлениями из дочерней формы.
Структура компонентов приведена ниже:
Родительский компонент
Главный родительский компонент выглядит следующим образом. Он хранит массив people
в состоянии. Он также передает функцию onPersonSaved
компоненту PersonEditor
. onPersonSaved
вызывается при нажатии кнопки сохранения редактора (подробнее об этом позже) и просто добавляет (без изменения) нового человека в массив people
const Parent = () => {
const [people, setPeople] = useState( [
{ id: 1, firstName: "John", lastName: "Smith" },
{ id: 2, firstName: "Peter", lastName: "Jones" },
{ id: 3, firstName: "Sally", lastName: "Wilson" },
]);
const onPersonSaved = (person) => {
setPeople([...people, person]);
}
const addNew = () => {
onPersonSaved({ id: 4, title: "Jane", url: "Johnson" });
};
return (
<div>
<Button type="button" onClick={addNew} content="Add Jane" />
<PersonEditor
onSubmit={onPersonSaved}
person={people[0]}
/>
</div>
);
};
export default Home;
Дочерняя форма
Дочерняя форма определена ниже. Это достаточно просто, и человек может редактировать его через свой person
prop. Он сохраняется в состоянии и обновляется с использованием useEffect
, если свойство person
изменяется.
Он также использует настраиваемый обработчик useForm
для поддержания состояний поля и запуска обратного вызова onPersonSaved
. Для информации, Button
и Input
являются компонентами semanti c -ui-react.
const PERSON_INITIALVALUE = {
id: null,
firstName: "",
lastName: ""
}
const PersonEditor = (props) => {
const [person, setLink] = useState(PERSON_INITIALVALUE);
const personForm = useForm(person, {
submit: (values) => {
if (props.onSubmit) {
props.onSubmit(values);
setLink(PERSON_INITIALVALUE);
}
},
});
useEffect(() => {
if (props.person) {
setLink({ ...props.person });
}
}, [props.person]);
return (
<Fragment>
<Input
type="text"
name="firstName"
value={personForm.values.firstName}
onChange={(e, data) => personForm.setField("firstName", data.value)}
/>
<Input
type="text"
name="lastName"
value={personForm.values.lastName}
onChange={(e, data) => personForm.setField("lastName", data.value)}
/>
<Button
type="button"
primary
content="Save Person"
onClick={personForm.submit}
/>
</Fragment>
);
};
Перехватчик useForm
Это настраиваемый перехватчик, который обеспечивает очень простую функциональность обработки формы, а именно управление полями и метод отправки. Он принимает набор начальных значений (в данном случае объект человека) и объект параметров, который в данном случае является просто свойством / функцией submit
.
const useForm = (initialValues, opts) => {
const [options] = useState(opts);
const [values, setValues] = useState({});
useEffect(() => {
if (initialValues) {
setValues({ ...initialValues });
}
}, [initialValues]);
const setField = (field, value) => {
setValues({ ...values, [field]: value });
};
const submit = () => {
options.submit(values);
};
return {
setField,
values,
submit,
};
};
export default useForm;
Проблема
Когда я добавляю нового человека через форму, он без проблем добавляет его в массив на вид . Однако, когда я добавляю еще одного человека, этот человек добавляется, но до того, как это произойдет, массив people
, кажется, вернулся / сброшен до исходного начального значения.
Итак, при первом добавлении в массив входят три исходных человека плюс новый человек, добавленный через редактор. Следовательно, массив имеет вид [John, Peter, Sally, FIRST NEW PERSON]
. При втором добавлении в массиве есть исходные три человека, но не осталось первого человека, но добавлено второе лицо. Массив выглядит так: [John, Peter, Sally, SECOND NEW PERSON]
Если я вызываю функцию onPersonSaved
непосредственно из родительского компонента, нажав кнопку Add Jane
, я могу добавлять Джейн столько раз, сколько захочу, и people
Массив состояний ведет себя так, как ожидалось.
Почему при использовании формы и настраиваемой ловушки состояние не сохраняется и почему оно сбрасывается до своего начального значения?