React-Final-Form:从 props 设置初始值,在 props 更改时重置表单状态

ama*_*iny 6 final-form react-final-form

我有一个组件,它需要一个balance道具,这个平衡道具会随着时间的推移而改变。

然后我有一个 React Final Form 来发送交易,通常的字段是发送金额,接收者......在我的 . 中validate,我只是检查用户是否有足够的余额来发送交易。

但是,如果我的余额在用户输入内容时发生变化,则整个表单将重置。你将如何只重置表单状态的一部分?

请参阅此代码和框示例:https : //codesandbox.io/s/jn69xql7y3 :

  • 输入东西
  • 等待 5 秒
  • 再次看到表单状态为空白

dav*_*wil 11

我刚刚遇到了这个问题,react-final-form当包装组件中发生任何状态更改时,表单会完全重置。

问题就在这里(来自你的代码和盒子)

<Form
  initialValues={{ amount: 0, balance }} <-- creates a new object on every render
Run Code Online (Sandbox Code Playgroud)

问题是当initialValues更改整个表单时会重新初始化。默认情况下,您传递给的任何内容都initialValues使用浅等于与前一个进行比较,即比较参考。

这意味着如果你在渲染中创建一个新对象,即使它是相同的,当某些状态发生变化时,整个表单会重置,渲染函数重新运行,并为initialValues.

为了解决一般问题,如果您只想关闭表单重置,我所做的只是将initialState永远不会改变的my移出到一个变量,以便它在每次渲染时都是相同的引用,因此总是出现与具有默认行为的 final-form 相同。我更喜欢一种配置来真正完全关闭这种重新初始化行为,但我在文档中找不到。

但是,如果您确实想要这个,但需要修改它,则可以使用initialValuesEqual道具(此处的文档)配置比较行为initialValues,例如对对象进行深入比较。

您还可以使用keepDirtyOnReinitializeprop 来仅重置表单中未被触及的部分。

我猜想以上的一些组合可能会解决您的用例,具体取决于您需要的确切 UX。


Cor*_*son 8

添加到@davnicwil 提到的内容,我的解决方案是useMemo()在 func 组件中挂钩:

const initialValues = useMemo(() => ({ amount: 0, balance }), [])
Run Code Online (Sandbox Code Playgroud)

通过使用useMemo它,在组件的生命周期内仅创建 1 个对象,随后的重新渲染不会导致 initialValues 覆盖表单值。


Cor*_*son 7

另一个解决方案是使用react-final-form Form propinitialValuesEqual={() => true}

<Form initialValues={{ amount: 0, balance }} initialValuesEqual={() => true} .../>
Run Code Online (Sandbox Code Playgroud)

参考: https: //github.com/final-form/react-final-form/issues/246