@lexstile

Как правильно скрестить formik, vkui и загрузку файла?

Компоненты: File, Formik

В чем сложность:
  • Нужно делать костыль с помощью - setFieldValue и setTouched
  • Пришлось описать обработку onInput прямо в render, т. к. сеттеры доступны только в нем при текущем подходе.


61e14e7b022e7253774079.png

Посмотреть код
const ProjectNewPage = ({ id }) => {
  const history = useHistory();

  const [logoUrl, setLogoUrl] = useState(null);

  const goBack = () => history.goBack();

  const onSubmit = (values, { setSubmitting }) => {
    console.log('values', values);
    setSubmitting(false);
  };

  return (
    <View id={id} activePanel="main">
      <Panel id="main">
        <PanelHeader left={<PanelHeaderBack onClick={goBack} />}>Новый проект</PanelHeader>
        <Group>
          <Formik
            validationSchema={ProjectNewSchema}
            initialValues={{ [FIELDS.LOGO]: null }}
            onSubmit={onSubmit}
          >
            {({ dirty, isValid, isSubmitting, setFieldValue, setTouched }) => (
              <Form>
                <Field name={FIELDS.LOGO}>
                  {({ meta }) => (
                    <SimpleCell disabled before={<Avatar size={64} src={logoUrl} />}>
                      <FormItem top="Логотип проекта" status={getFieldStatus(meta)} bottom={meta.touched && meta.error}>
                        <File
                          name={FIELDS.LOGO}
                          stretched
                          before={<Icon24Camera />}
                          controlSize="l"
                          mode="secondary"
                          accept="image/jpeg,image/png"
                          onInput={(event) => {
                            const file = get(event, 'target.files.0', '');
                            const fileSize = get(file, 'size', 0);

                            !meta.touched && setTouched({ [FIELDS.LOGO]: true });

                            if (fileSize > 0 && fileSize <= MAX_SIZE_IMAGE) {
                              const reader = new FileReader();

                              reader.onload = (e) => setLogoUrl(get(e, 'target.result', ''));
                              reader.readAsDataURL(file);

                              setFieldValue(FIELDS.LOGO, file);
                            }
                          }}
                        />
                      </FormItem>
                    </SimpleCell>
                  )}
                </Field>
                <FormItem>
                  <Button
                    stretched
                    type="submit"
                    size="l"
                    before={isSubmitting && <Spinner size="small" style={{ color: 'var(--white)' }} />}
                    disabled={!dirty || !isValid || isSubmitting}
                  >
                    Добавить
                  </Button>
                </FormItem>
              </Form>
            )}
          </Formik>
        </Group>
      </Panel>
    </View>
  );
};
  • Вопрос задан
  • 103 просмотра
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
28 нояб. 2024, в 21:25
5000 руб./за проект
28 нояб. 2024, в 18:46
3000 руб./за проект
28 нояб. 2024, в 17:46
10000 руб./за проект