React-Final-Form: установить initialValues ​​из реквизита, состояние формы сбрасывается при смене реквизита

У меня есть компонент, который занимает balance опора, и этот баланс пропел может меняться со временем.

Затем у меня есть React Final Form для отправки транзакции с обычным количеством полей для отправки, получателем... И в моем validateЯ просто проверяю, достаточно ли у пользователя баланса для отправки транзакции.

Однако, если мой баланс изменяется, когда пользователь что-то вводит, тогда вся форма сбрасывается. Как бы вы сбросили только часть состояния формы?

См. Этот код и окно для примера: https://codesandbox.io/s/jn69xql7y3:

  • введите что-то
  • подождите 5 с
  • увидеть, что состояние формы снова пустое

0 ответов

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

Проблема здесь (из вашего codeandbox)

<Form
  initialValues={{ amount: 0, balance }} <-- creates a new object on every render

Проблема в том, что когда initialValuesизменяет всю форму повторно инициализируется. По умолчанию все, что вы передаетеinitialValuesсравнивается с предыдущим с использованием неглубоких равенств, то есть сравнения ссылок.

Это означает, что если вы создаете новый объект в рендере, даже если он такой же, вся форма сбрасывается при изменении какого-либо состояния, функция рендеринга запускается повторно, и новый объект с новой ссылкой создается для initialValues.

Чтобы решить общую проблему, если вы просто хотите отключить сброс формы, я просто переместил initialState, который никогда не изменяется, на переменную, так что это одна и та же ссылка при каждом рендеринге и, следовательно, всегда кажется одинаковой для final-form с поведением по умолчанию. Я бы предпочел, чтобы конфигурация полностью отключила это поведение при повторной инициализации, но я не могу найти его в документации.

Однако, если вы действительно этого хотите, но вам нужно его изменить, поведение сравнения можно настроить с помощью initialValuesEqualprop (документы здесь), чтобы провести глубокое сравнениеinitialValues объект например.

Вы также можете использовать keepDirtyOnReinitialize prop, чтобы сбросить только те части вашей формы, которые не были затронуты.

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

Добавляя к тому, что упомянул @davnicwil, мое решение useMemo() подключить компоненты func:

const initialValues = useMemo(() => ({ amount: 0, balance }), [])

Используя useMemo он создает только 1 объект в течение срока службы компонента, и последующие повторные отрисовки не приводят к перезаписи значений формы в initialValues.

Другое решение - использовать опору формы response-final-form initialValuesEqual={() => true}

<Form initialValues={{ amount: 0, balance }} initialValuesEqual={() => true} .../>

ссылка: https://github.com/final-form/react-final-form/issues/246

Другие вопросы по тегам