Сброс заголовка типа реакции-бустрапа с помощью formik
Вместе с Formik я использую AsyncTypeahead из библиотеки activ-boostrap-typeahead. Обе замечательные маленькие библиотеки. Упрощенная версия моего кода выглядит следующим образом
const SearchFilter = withFormik({
mapPropsToValues: (props) {
office: someIncomingValue || [{name: 'office1', id: 1}]
}
})(TheForm)
const TheForm = (props) => {
const {values, handleReset} = props;
return (
<form>
<AsyncTypeahead
defaultSelected={[values.office]}
options={...}
onChange={...SetNewValue...}
onSearch={...}/>
<button onClick={handleReset}
</form>
)
}
Используя свойство defaultSelected в AsynchTypeahead. Я могу установить начальное значение по умолчанию. Но у меня возникает проблема, когда я нажимаю кнопку для handleRest, formik делает свое дело и сбрасывает значение обратно в office 1, но AsynchTypeahead не имеет способа вручную передать значение обратно в него. Так что не меняется. Я видел, что есть selected
опора доступна, но она просто взрывается, когда я пытаюсь ее использовать. Любой вклад будет герат
ОБНОВИТЬ:
Да, выбрано то, что мне нужно. Мне пришлось добавить свойство onInputChange, чтобы сохранить родителя в синхронизации с тем, что печаталось.
1 ответ
У меня такой же вопрос.
Я придумал это решение:
import { Formik } from "formik";
import * as Yup from "yup";
import { Typeahead } from 'react-bootstrap-typeahead';
const AddCheckSchema = Yup.object().shape({
title: Yup.string()
.min(2, 'Too Short!')
.max(50, 'Too Long!')
.required('Required')
});
...
render() {
const users = [
{ id: 1, fullname: 'User #1' },
{ id: 2, fullname: 'User #2' },
{ id: 3, fullname: 'User #3' },
];
return (
<Formik
initialValues={{
title: '',
amount: 0,
actualDate: new Date()
}}
validationSchema={AddCheckSchema}
onSubmit={ this.onSubmit}
>
{({
errors,
touched,
handleChange,
handleBlur,
handleSubmit,
setFieldValue,
setFieldTouched,
}) => (
<form onSubmit={handleSubmit}>
<div className="form-group required">
<label className="control-label">Title:</label>
<Typeahead
multiple={false}
onChange={(selected) => {
const value = (selected.length > 0) ? selected[0].fullname : '';
setFieldValue('title', value);
}}
onInputChange={(text, event) => setFieldValue('title', text)}}
onBlur={(e) => setFieldTouched('title', true)}
labelKey="fullname"
options={users}
/>
<div className="text-danger">{touched.title && errors.title}</div>
</div>
<div className="form-group">
<button type="submit" className="btn btn-primary btn-lg">Add check</button>
</div>
</form>
)}
</Formik>
)
}
Конечно, вы можете извлечь эту сложную логику (вокруг поля Typeahead) в отдельный компонент.
В моем случае мне пришлось выбрать более простое решение, взглянув на этот пример здесь https://ericgio.github.io/react-bootstrap-typeahead/#basic-example
export const SelectSearch = ({name, value, schema, setFieldValue, errors}) => {
const [singleSelections, setSingleSelections] = useState([]);
useEffect(() => {
if (singleSelections.length > 0) {
setFieldValue(name, singleSelections[0].value)
}
}, [singleSelections])
return (
<LabeledField name={name} schema={schema}>
<Typeahead
id="basic-typeahead-single"
multiple={false}
labelKey="label"
options={schema.choices}
onChange={setSingleSelections}
isInvalid={!!errors[name]}
placeholder="Choose a state..."
selected={singleSelections}
/>
<Form.Control.Feedback type="invalid">
{errors[name]}
</Form.Control.Feedback>
</LabeledField>
)
}
Затем этот компонент можно отобразить в контексте formik, как показано ниже.
const Component = () => {
return (
<Formik
initialValues={...}
validationSchema={AddCheckSchema}
onSubmit={this.onSubmit}
>
{({
errors,
touched,
handleChange,
handleBlur,
handleSubmit,
setFieldValue,
setFieldTouched,
}) => (
<form onSubmit={handleSubmit}>
<div className="form-group required">
<label className="control-label">Title:</label>
<SelectSearch
name={"inputName"}
choices={choices}
setFieldValue={setFieldValue}
errors={errors}
/>
</div>
<div className="form-group">
<button type="submit" className="btn btn-primary btn-lg">Submit</button>
</div>
</form>
)}
</Formik>
)
}