Вот как я это делаю (при условии, что ваши входные данные должны быть внутри формы):
У меня есть компонент BasicForm, который я использую.
Он сохраняет все входные состояния в объекте водин вызов useState ().
Он проходит через useContext()
состояние inputs
вместе с функцией onChange()
и функцией setInputInitialState()
для входов, чтобы установить их начальное состояние при первом подключении,Он также передает onFocus, onBlur и имеет функции для проверки полей, которые я здесь не показываю для упрощения кода.
Таким образом, я могу легко создать форму с таким количеством входов, как я хочу, например:
<BasicForm
isSubmitting={props.isSubmitting}
submitAction={ (formState) =>
props.doSignIn(formState) }
>
<TextInput
type='email'
label='Email'
name='email'
placeholder='Enter email...'
required
/>
<TextInput
type='password'
label='Password'
name='password'
placeholder='Enter password...'
min={6}
max={12}
required
/>
<SubmitButton
label='Login'
/>
</BasicForm>
BasicForm.js
import FormContext from './Parts/FormContext';
function BasicForm(props) {
const [inputs, setInputs] = useState({});
function onChange(event) {
const newValue = event.target.value;
const inputName = event.target.name;
setInputs((prevState)=> {
return({
...prevState,
[inputName]: {
...prevState[inputName],
value: newValue,
dirty: true
}
});
});
}
function setInputInitialState(
inputName,
label='This field ',
type,
initialValue = '',
min = false,
max = false,
required = false) {
const INITIAL_INPUT_STATE = {
label: label,
type: type,
onFocus: false,
touched: false,
dirty: false,
valid: false,
invalid: false,
invalidMsg: null,
value: initialValue,
min: min,
max: max,
required: required
};
setInputs((prevState) => {
if (inputName in prevState) {
return prevState;
}
return({
...prevState,
[inputName]: INITIAL_INPUT_STATE
});
});
}
return(
<FormContext.Provider value={{
onChange: onChange,
inputs: inputs,
setInputInitialState: setInputInitialState,
}}>
<form onSubmit={onSubmit} method='POST' noValidate>
{props.children}
</form>
</FormContext.Provider>
);
}
TextInput.js
В качестве ввода используется хук useEffect()
чтобы установить их начальное состояние, когда они смонтированы.
function TextInput(props) {
const formContext = useContext(FormContext);
useEffect(() => {
console.log('TextInput useEffect...');
formContext.setInputInitialState(
props.name,
props.label,
props.type,
props.initialValue,
props.min,
props.max,
props.required
);
},[]);
return(
<input
type={props.type}
id={props.name}
name={props.name}
placeholder={props.placeholder}
value={([props.name] in formContext.inputs) ?
formContext.inputs[props.name].value
: props.initialValue || ''}
onChange={formContext.onChange}
onFocus={formContext.onFocus}
onBlur={formContext.onBlur}
>
</input>
</div>
{([props.name] in formContext.inputs) ?
formContext.inputs[props.name].invalidMsg && <div><span> {formContext.inputs[props.name].invalidMsg}</span></div>
: null}
</div>
);
...
}