如何 set/change 来自外部用户操作的字段值 React Final Form

How to set/change Field value from external user action React Final Form

在很多情况下,我们可能希望在表单中设置特定字段的值来帮助用户。

例如,在线水果店可能会询问用户他们想要购买多少个苹果。为了帮助用户,我们可以有 3 个按钮,例如

在回顾了我认为最相关的两个示例 (Loading and Initializing Values and Calculated Fields) 之后,我仍然想不通这一个,除非太老套了。

我们如何根据用户的操作(例如单击按钮)设置字段的值

这可以通过向 Form 组件提供一个 mutators 对象来实现,其中包含必要的修改器,这些修改器将可供您的组件使用:

<Form
  mutators={{
    setMin: (args, state, utils) => {
      utils.changeValue(state, 'apples', () => 1)
    },
    setMax: (args, state, utils) => {
      utils.changeValue(state, 'apples', () => 100)
    },
    setLast: (args, state, utils) => {
      utils.changeValue(state, 'apples', () => 6)
    },
  }}
  
  render={({ form, ...rest }) => (
    <>
      <button onClick={form.mutators.setMin}>minimum apples</button>
      <button onClick={form.mutators.setMax}>maximum apples</button>
      <button onClick={form.mutators.setLast}>what I bought last time</button>
    </>
  )}
/>
  

正如下面@davnicwil 所建议的,如果您需要从 React 应用程序外部与表单交互(例如,您正在使用 micro front-ends,您正在迁移应用程序,或者有一些第三方party 库在 React 之外)你可以使用 render 方法将表单对象(或其中的任何方法)保存到全局范围,并根据需要调用它们:

render={({ form, ...rest }) => {
  window.form = form;

  // ... rest of code
)}

// later anywhere else in app
window.form.mutators.setMax

Erik's post

接受的答案很好,并引导我找到了我的解决方案,但万一有人像我一样来到这里寻找一种方法来从 React 应用程序外部修改字段值 ,您可以通过创建一个完全通用的修改器来实现,该修改器将任何字段设置为任何值,并以这样的形式获取对绑定修改器的全局引用

<Form
  mutators={{
    // expect (field, value) args from the mutator
    setValue: ([field, value], state, { changeValue }) => {
      changeValue(state, field, () => value)
    }
  }}
  render={({ form, ...rest }) => {
    // put the reference on a window variable of your choice here
    if (!window.setFormValue) window.setFormValue = form.mutators.setValue

    return (
      <>
        <Field name="field1">...</Field>
        <Field name="field2">...</Field>
        ...
      </>
    )
  }}
/>

// somewhere else, outside of the React application

window.setFormValue('field1', 'value1')
window.setFormValue('field2', 'value2')

以上内容适用于 v5.0.0 及更高版本。在早期版本中,API 略有不同。不要使用 form.mutators,而是使用顶级 mutators 属性作为渲染函数,即 render={({ mutators, ... }

免责声明:对于非常特殊的用例,除非绝对必要,否则不应使用此模式。例如,我正在使用它来自动填充来自 必须 在我的 React 应用程序外部的代码的字段。您不应该为实际的应用程序代码执行此操作。但如果你确实需要这样做,它会很好用!