Material-ui: Работа с React-Hook-Form

Созданный на 8 нояб. 2019  ·  40Комментарии  ·  Источник: mui-org/material-ui

Я пытаюсь создать простую форму с помощью react-hook-form и material-ui . Я бы хотел уметь:

  1. отправить / подтвердить форму
  2. сбросить форму правильно
  3. загрузить данные правильно

Извините, поиск плохой проблемы, похоже, дубликат https://github.com/mui-org/material-ui/issues/17018.

  • [x] Проблема присутствует в последней версии.
  • [x] Я искал проблемы в этом репозитории и считаю, что это не дубликат.

Текущее поведение 😯

Первый шаг работает правильно.
Функция сброса очищает значение, но состояние текстового поля material-ui, похоже, остается на «заполненном», а стили не совпадают с очищенными данными.
Функция сброса с начальными значениями правильно устанавливает значение, но поведение такое же, как и при сбросе (ну, в данном случае наоборот), данные загружаются, но внутреннее состояние TextField не "заполнено".

Ожидаемое поведение 🤔

Вход material-ui должен обновлять свое внутреннее состояние, когда данные загружаются / очищаются.

Шаги по воспроизведению 🕹

Вы можете попробовать три кнопки на этом CodePen:
https://codesandbox.io/s/material-demo-ywutu

  1. Отправить: корректно работает с проверкой данных.
  2. Сбрасывается правильно, но состояние текстовых полей не пустое.
  3. Правильно загружает данные, но состояние текстовых полей не заполняется.

Я зарегистрировал проблему в проекте response-hook-form, но владелец сказал мне открыть и здесь, так что мы здесь :)

enhancement external dependency

Самый полезный комментарий

Я добавил тег waiting for users upvotes . Я закрываю вопрос, так как мы не уверены, что люди ищут такую ​​поддержку. Так что, пожалуйста, проголосуйте за этот вопрос, если да. Мы будем определять приоритеты наших усилий в зависимости от количества голосов.

https://npm-stat.com/charts.html?package=formik&package=react-hook-form&package=react-final-form

Все 40 Комментарий

Я добавил тег waiting for users upvotes . Я закрываю вопрос, так как мы не уверены, что люди ищут такую ​​поддержку. Так что, пожалуйста, проголосуйте за этот вопрос, если да. Мы будем определять приоритеты наших усилий в зависимости от количества голосов.

https://npm-stat.com/charts.html?package=formik&package=react-hook-form&package=react-final-form

очень нужен: молиться :: молиться :: молиться: какое-либо решение?

так нужно!

Определенно нужно.

Есть идеи, каким будет решение?

Я не уверен в чем-то конкретном, но я знаю, что начал использовать обе библиотеки, и мне действительно хотелось бы видеть более тесную интеграцию между ними. React Hook Form и Material UI просто великолепны вместе. Их поддержка TypeScript тоже хороша.

Привет, @oliviertassinari, спасибо, что взглянули на это. Похоже, MUI TextField теперь лучше работает с API встроенного ввода! Это действительно мило. Раньше при вызове e.target.value = 'xxx' поверх текста накладывался текст-заполнитель. 👍

Screen Shot 2019-11-20 at 10 06 26 am

https://codesandbox.io/s/react-hook-form-conditional-fields-delete-1frsm
В приведенном выше примере <Switch /> не сбрасывается после вызова reset API.

Было бы очень хорошо, если бы мы могли иметь все компоненты, связанные с формой, для поддержки собственного API ввода формы (установка и сброс значения через ссылку на ввод). Я понимаю, что это большая часть работы, и поддержка небольшой библиотеки, такой как react-hook-form, - это что-то, что нужно учитывать (возможно, до тех пор, пока библиотека не станет более популярной ❤️)

Опять же, я ценю ваше время и усилия, чтобы разобраться в этой проблеме (поддерживать ОГРОМНЫЙ проект с открытым исходным кодом, такой как MUI для меня безумие, и вы делаете потрясающую работу для сообщества React). Вдобавок ко всему, дайте мне знать, могу ли я поработать над своей стороной, чтобы работать и с MUI.

Ваше здоровье
Билл

@ bluebill1049 Спасибо, что посмотрели на это. Библиотека вроде набирает обороты, но формик все равно сильно отстает. Сброс переключателя - единственная проблема, которая у нас есть?

спасибо, @oliviertassinari за повторное открытие и react-hook-form все еще молодой парень в городе, и вам не нужно действовать, если вы хотите еще немного подождать, чтобы увидеть, будут ли другие пользователи использовать react-hook-form , который Я думаю, что это совершенно разумно (даже если в глубине души я отчаянно хочу, чтобы он работал с MUI, хахаха, было эгоистично😼). А пока я создам таблицу входов, совместимую с react-hook-form из коробки (возможно, даже с codeandbox). Я также опубликую ее здесь.

Если все работает хорошо с формой реагирующего крючка и расширением использования, возможно, мы можем рассмотреть возможность работы с собственным API ввода (который используется за кулисами в форме реагирующего крючка), было бы здорово получить input , select , radio и checkbox как они являются основным использованием формы.

FYI @oliviertassinari Я работаю над чем-то, чтобы сократить разрыв между MUI и формой реакции. https://github.com/react-hook-form/react-hook-form-input

Также возникает проблема со сбросом и загрузкой данных по умолчанию. Пожалуйста, изучите эту проблему. Или, по крайней мере, пока что предоставьте обходной путь.

Привет, @raikusy, пожалуйста, взгляните на ссылку, которую я разместил выше, я думаю, она вам поможет. В долгосрочной перспективе было бы здорово, если бы компонент MUI поддерживал нативную форму api 'reset' и обновлял значение через компонент 'ref', но это большая цена работы, и я уверен, что у MUI есть много функций и идей. которые более важны. Так же, как мы обсуждали выше, до тех пор, пока форма react hook не станет основной библиотекой или не станет популярной, MUI начнет поиск решений. Надеюсь, в этом есть смысл :) Спасибо, что тоже используете форму реагирования

К вашему сведению, этот компонент-оболочка по-прежнему позволит ur-форме иметь 0 повторных рендерингов. Поскольку обновление состояния ввода изолировано внутри компонента-оболочки.

Спасибо @ bluebill1049, это отлично выглядит. У меня есть условие, при котором поля формы будут иметь значение по умолчанию, когда данные передаются из реквизита. Так будет ли компонент TextField работать с указанным выше решением? Также я искал лучший пример передачи значений по умолчанию с реквизитами в форму. Реквизиты могут когда-нибудь поступать из вызова api после того, как форма уже смонтирована.

@raikusy, вы должны иметь возможность использовать reset / setValue API с компонентом оболочки.
сбросить: для всей формы -> https://react-hook-form.com/api#setValue
setValue: для индивидуального -> https://react-hook-form.com/api#reset

Я не могу заставить <Slider /> работать с RHF.

Используя это как:

      <FormControl fullWidth component="fieldset" margin="normal">
        <FormLabel component="legend">Palavras</FormLabel>
        <RHFInput
          as={<Slider min={100} max={1200} step={100} valueLabelDisplay="auto" marks={marks} />}
          type="input"
          name="words"
          register={register}
          setValue={setValue}
        />
      </FormControl>

Я получаю следующую ошибку:

Warning: Failed prop type: Invalid prop `value` supplied to `ForwardRef(Slider)`.
    in ForwardRef(Slider) (created by WithStyles(ForwardRef(Slider)))
    in WithStyles(ForwardRef(Slider)) (created by SetupAccountForm)
    in Unknown (created by SetupAccountForm)
    in fieldset (created by ForwardRef(FormControl))
    in ForwardRef(FormControl) (created by WithStyles(ForwardRef(FormControl)))
    in WithStyles(ForwardRef(FormControl)) (created by SetupAccountForm)
    in form (created by SetupAccountForm)
    in SetupAccountForm (created by SetupAccountPage)
    in div (created by ForwardRef(CardContent))
    in ForwardRef(CardContent) (created by WithStyles(ForwardRef(CardContent)))
    in WithStyles(ForwardRef(CardContent)) (created by SetupAccountPage)
    in div (created by ForwardRef(Paper))
    in ForwardRef(Paper) (created by WithStyles(ForwardRef(Paper)))
    in WithStyles(ForwardRef(Paper)) (created by ForwardRef(Card))
    in ForwardRef(Card) (created by WithStyles(ForwardRef(Card)))
    in WithStyles(ForwardRef(Card)) (created by SetupAccountPage)
    in div (created by ForwardRef(Grid))
    in ForwardRef(Grid) (created by WithStyles(ForwardRef(Grid)))
    in WithStyles(ForwardRef(Grid)) (created by Layout)
    in Layout (created by SetupAccountPage)
    in SetupAccountPage (created by App)
    in Route (created by App)
    in Switch (created by App)
    in Router (created by HashRouter)
    in HashRouter (created by App)
    in App (created by Root)
    in div (created by ForwardRef(Container))
    in ForwardRef(Container) (created by WithStyles(ForwardRef(Container)))
    in WithStyles(ForwardRef(Container)) (created by Root)
    in div (created by Styled(MuiBox))
    in Styled(MuiBox) (created by Root)
    in Provider (created by Root)
    in Root Button.js:233:15

@hbarcelos выглядит так, как будто слайдер не поддерживает проведу небольшое расследование по этому поводу. А пока вам, возможно, придется использовать настраиваемый регистр, который регистрируется в useEffect

Большое спасибо @ bluebill1049

В итоге я сделал что-то вроде этого:

import React, { useEffect, useCallback, useState, useMemo } from 'react';
import t from 'prop-types';
import clsx from 'clsx';
import { makeStyles } from '@material-ui/core/styles';
import Box from '@material-ui/core/Box';
import Slider from '@material-ui/core/Slider';

const useStyles = makeStyles(theme => ({
  sliderWrapper: {},
  sliderLabel: {
    marginTop: theme.spacing(1),
    marginBottom: theme.spacing(0.5),
    color: theme.palette.primary.main,
  },
}));

function CustomSlider({
  register,
  unregister,
  setValue,
  name,
  rules,
  defaultValue,
  valueLabelAs,
  formatLabel,
  ...rest
}) {
  const cl = useStyles();

  const [currentValue, setCurrentValue] = useState(defaultValue);

  useEffect(() => {
    register({ name });
    return () => unregister(name);
  }, [defaultValue, name, register, setValue, unregister]);

  const valueLabel = useMemo(() => {
    if (!valueLabelAs) {
      return null;
    }

    return React.cloneElement(
      valueLabelAs,
      { className: clsx(valueLabelAs.props.className, cl.sliderLabel) },
      formatLabel(currentValue)
    );
  }, [cl.sliderLabel, currentValue, formatLabel, valueLabelAs]);

  const handleChange = useCallback(
    (_, value) => {
      setValue(name, value);
      setCurrentValue(value);
    },
    [name, setValue]
  );

  return (
    <React.Fragment>
      {valueLabel}
      <Box className={cl.sliderWrapper}>
        <Slider {...rest} onChange={handleChange} defaultValue={defaultValue} />
      </Box>
    </React.Fragment>
  );
}

CustomSlider.defaultProps = {
  rules: {},
  defaultValue: '',
  valueLabelAs: null,
  formatLabel: v => v,
};

CustomSlider.propTypes = {
  register: t.func.isRequired,
  unregister: t.func.isRequired,
  setValue: t.func.isRequired,
  name: t.string.isRequired,
  rules: t.object,
  defaultValue: t.oneOfType([t.number, t.string]),
  valueLabelAs: t.node,
  formatLabel: t.func,
};

export default CustomSlider;

Работает как положено.

Это тоже очень нужно

В конечном итоге было бы здорово, если бы компонент MUI поддерживал «сброс» API нативной формы и обновлял значение через компонент «ref».

@ bluebill1049 Разве это не проблема React или самой формы
Скажем, я разработчик React, создающий пользовательский ввод, и я хочу по-другому стилизовать элемент, когда он заполнен / пуст, как мне это реализовать? Кажется, что событие изменения никогда не запускается.

Рассматривали ли вы запуск события изменения, когда ваша библиотека изменяет входное значение «вне» декларативной модели React? Как это сделано в @ test-library / react?

Это позволит поддерживать компоненты Material-UI, которые полагаются на собственные элементы ввода, для других, таких как Slider, по-прежнему потребуется настраиваемая оболочка. Ползунок имеет свойство value, но сигнатура onChange отличается от собственного ввода. Я думаю, что было бы здорово увидеть такую ​​же библиотеку интеграции, как и другие библиотеки форм: # 15585.


Мне было интересно, почему этот выпуск получил столько голосов, думаю, что я узнал 🙃:

Capture d’écran 2019-12-07 à 20 41 31
https://react-hook-form.com/advanced-usage#ControlledmixedwithUncontrolledComponents

привет @oliviertassinari , спасибо, что снова внимательно изучили этот вопрос 👍

Скажем, я разработчик React, создающий пользовательский ввод, и я хочу по-другому стилизовать элемент, когда он заполнен / пуст, как мне это реализовать? Кажется, что событие изменения никогда не запускается.

Я бы искал селектор CSS для решений в моем собственном проекте, который использует собственные входы, например: выберите элемент с пустым значением и отобразите стиль. В качестве альтернативы я бы использовал response-hook-form watch API, чтобы обнаружить пустое значение и передать его как prop (с моим обернутым входным компонентом).

Рассматривали ли вы запуск события изменения, когда ваша библиотека изменяет входное значение «вне» декларативной модели React? Как это сделано в @ test-library / react?

Да, мы в значительной степени делаем это под react-hook-form-input . 😄

Я верю в неконтролируемые компоненты для строительных форм после многих лет контроля строительных форм, это действительно значительно упрощает работу. Возможно, он не решит все крайние случаи (если вы работаете в Facebook LOL), но, безусловно, облегчит мою рабочую жизнь и окружающих меня людей, когда дело доходит до создания форм. HTML-входы сами по себе сохраняют состояние, и я хотел бы включить их в эту библиотеку (не говоря, что это правильно или неправильно, но как альтернативное решение).

Мне так нравится создавать приложение React, поэтому я создаю вокруг него множество пакетов. Я понимаю, что React охватывает контролируемые компоненты. Однако форма react-hook-form не мешает разработчикам управлять формой сборки, потому что вы все равно можете делать пользовательские register при useEffect .

Заключение:

Я думаю, что мы можем закрыть эту проблему, и я удалю ссылку на моем веб-сайте, связанную с этой проблемой. Кроме того, могу ли я обновить эту страницу, добавив react-hook-form-input ?

https://material-ui.com/components/text-fields/#complementary -projects

Да, мы в значительной степени делаем это в режиме ввода-ответа-крючка-формы.

@ bluebill1049 Похоже на противоположный подход к моему предложению. Я понимаю следующее:

  • форма реакции-крючка:

    1. Он отслеживает входные узлы DOM. Когда ему нужно изменить значение, он делает input.value = 'x' . Это проблематично для React, поскольку у него нет способа узнать, что входное значение изменилось. Например, событие изменения не запускается .

    2. Поскольку response-hook-form должен прослушивать изменения входного значения, он устанавливает на входе прослушиватель событий «input» . Это проблематично для вашей библиотеки, поскольку изменения React не вызывают никаких событий, когда значение изменяется с контролируемого ввода .

  • response-hook-form-input: библиотека управляет вводом, чтобы обойти два предыдущих ограничения response-hook-form (i и ii).

Учитывая, что 1. очень маловероятно, что React будет хорошо играть, поддерживая подход формы реакции-крючка и 2. эта форма-крюк-реакция не работает за пределами коробки с контролируемыми и псевдо-неконтролируемыми входами (теми, которые изменяют значение по умолчанию и те, которые слушают только onChange), я бы предложил следующее:

  1. react-hook-form исправляет контролируемые и псевдоконтролируемые проблемы изнутри. По сути, вам нужно решить i. и ii. (см. предлагаемые решения в связанных кодах и окнах: dispatch + defineProperty).
  2. Material-UI обращается за помощью к сообществу, чтобы предоставить адаптеры для формы реакции-крючка, когда это необходимо (относится к # 15585).
  3. Закрываем этот вопрос 👌

спасибо, @oliviertassinari за подробный ответ. Я проведу дополнительное исследование с вашими предлагаемыми решениями :)

Я считаю, что большая часть проблемы, о которой вы упомянули выше, с React, заключается в том, что вы переключаете управляемые компоненты, и это часть, которую я хочу улучшить.

Просто быть чистым:

  • Чтобы воспроизвести проблему при изменении , перейдите по адресу https://codesandbox.io/s/heuristic-galileo-1wf8c и нажмите кнопку => отсутствует журнал. Теперь перейдите на https://codesandbox.io/s/silly-allen-72zz7 и посмотрите, как диспетчерский подход решает проблему.
  • Чтобы воспроизвести проблему изменения значения , перейдите на https://codesandbox.io/s/elastic-agnesi-osuuy и нажмите кнопку => пропавший журнал. Теперь перейдите на https://codesandbox.io/s/sparkling-rain-3rebh и посмотрите, как подход Object.defiendProperty решает проблему.

Так что я почти уверен, что вы можете решить эту проблему в форме реакции на крючок. Мы будем признательны, если вы сможете попробовать / развернуть эти исправления и убрать вину с нашей стороны из своей документации 😛.

Эти изменения должны действительно помочь в развитии вашей библиотеки форм, я надеюсь, вы оцените это: D.

Я считаю, что большая часть проблемы, о которой вы упомянули выше, с React, возникает, когда вы переключаетесь с неконтролируемых компонентов на контролируемые или контролируемые, и это часть, которую я хочу улучшить.

React предупреждает, когда пользователь переключается между неконтролируемым и контролируемым. Я не понимаю твою точку зрения.

Так что я почти уверен, что вы можете решить эту проблему в форме реакции на крючок. Мы будем признательны, если вы сможете попробовать / развернуть эти исправления и убрать вину с нашей стороны из своей документации 😛.

НИ В КОЕМ СЛУЧАЕ Я не виню MUI, ха-ха, я люблю MUI (с моей маленькой звездочкой ⭐️). Как вы знаете, «react-hook-form» - молодой парень в городе, я пытался привлечь внимание или импульс к конкретному вопросу. Прошу прощения, если вы найдете такой способ (виноват). еще раз большое спасибо за вашу помощь и расследование.

image
(Не обвиняю)

Я считаю, что большая часть проблемы, о которой вы упомянули выше, с React, возникает, когда вы переключаетесь с неконтролируемых компонентов на контролируемые или контролируемые, и это часть, которую я хочу улучшить.

React предупреждает, когда пользователь переключается между неконтролируемым и контролируемым. Я не понимаю твою точку зрения.

извините, я имел в виду управляемый компонент :) исправил мой комментарий

@ bluebill1049 Замечательно :)

большое спасибо, @oliviertassinari (вы очень любезны)

Обратите внимание, что Material-UI может применять те же предлагаемые исправления, но я не думаю, что мы должны, у него было бы два недостатка: 1. он будет работать только с Material-UI, одни и те же усилия нужно будет делать снова и снова. 2. Право собственности на эти «хаки» должно оставаться в форме «реакция-крючок», поскольку это происходит из компромисса, принятого библиотекой (в обход идиоматического React API).

Привет, ребята, на случай, если кто-то вмешается в эту проблему. (Мы тайно работали над этим некоторое время 😓)

Мы работаем над следующей основной версией RHF, в которой есть некоторые обновления качества жизни, особенно в отношении управляемого компонента. У нас будет лучшая поддержка библиотеки пользовательского интерфейса. Следующий код разрешит setValue и defaultValue для управляемой библиотеки пользовательского интерфейса, при этом сохраняя минимальную повторную визуализацию на уровне вашего приложения / формы, повторная визуализация будет изолирована на уровне вашего входного компонента.

Ниже приводится синтаксис при использовании V4 RHF.

import TextField from '@material-ui/core/TextField';

const { control } = useForm();

<Controller as={TextField} control={control} name="firstName" rules={{ required: true }} />

Нужна помощь.
У меня проблема с текстовым полем материала (возможно, и с другим mui).
Когда текстовое поле пусто, первое хранилище ключей работает медленно, то же самое происходит, когда вы меняете значение на пустое.
По какой-то причине он повторно отображает всю форму.

Screen Shot 2020-02-11 at 3 21 25 AM

ezgif com-video-to-gif

БЫСТРОЕ ПРИМЕЧАНИЕ : Я печатаю быстро, без задержек. они задерживают часть из-за причины, упомянутой выше.

Привет, ребята, эта проблема сохраняется, даже если я использую контроллер из формы реакции :(
Можно ли снова открыть этот вопрос? Или я не так делаю?

Пример: https://codesandbox.io/s/example-muitextfield-setvalue-with-react-hook-form-kqwq0?file=/index.js

Изменить: решение, которое я использую, - это InputLabelProps={isEdition && { shrink: isEdition }}
где isEdition - это флаг, который я использую на экране редактирования.

@Luccasoli, пожалуйста, обратитесь к документу: https://react-hook-form.com/api#Controller

Вот пример с примерами MUI: https://codesandbox.io/s/react-hook-form-controller-079xx

Извините @ bluebill1049 , но я не нашел подобной ситуации в этом примере, а в документации я не нашел ни одной опоры, которая могла бы решить эту проблему должным образом :(

Screen Shot 2020-04-15 at 9 21 56 am

@Luccasoli взгляни на defaultValue

Я пытался:

  • Я попытался включить defaultValues ​​внутри useForm () в значение состояния и установить это состояние внутри useEffect ()
  • Я пробовал использовать ту же идею, но в опоре defaultValue напрямую каждый контроллер

В обоих случаях textField не распознает, что ввод заполнен, и метка сохраняется над вводом

Да, но это странно - сохранить такое значение по умолчанию, я всегда стараюсь начинать с пустого строкового значения, чтобы не показывать странное значение пользователю.

Я мог бы даже отобразить значение defaultValue «Загрузка», но пустое начальное значение все равно кажется более интересным. Как вы думаете, это возможно?

Изменить: да, работает и с пустой строкой ... хахаха, спасибо, я клялся, что пробовал это раньше, но похоже, что это так.

@ bluebill1049 Я
https://codesandbox.io/s/react-hook-form-controller-n196b?file=/src/index.js
Перед включением кнопки отмечается попытка проверки флажка. Все остальные поля, которые я использовал, работают должным образом, за исключением флажка.

Я нашел эту песочницу действительно очень полезной для пользовательского интерфейса материала - есть примеры для ползунков, выбора и некоторых других.
https://codesandbox.io/s/react-hook-form-controller-079xx?file=/src/index.js

Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

TimoRuetten picture TimoRuetten  ·  3Комментарии

ericraffin picture ericraffin  ·  3Комментарии

reflog picture reflog  ·  3Комментарии

sys13 picture sys13  ·  3Комментарии

finaiized picture finaiized  ·  3Комментарии