使用 object/props 使用 mobx-react-form 设置表单值

Set form values with mobx-react-form using object/props

我正在使用 mobx-react-form,我需要使用从我商店中的对象中提取的默认值来填充表单。不幸的是,如果我尝试使用 FormModel.$("email").set(object.email);在我的组件内部,mobx 抱怨我无法在动作之外修改观察到的对象,并且我超过了 maxdepth。

具体来说,我的代码如下所示(为清楚起见删除了一些细节)

import React from 'react';
import ReactDOM from "react-dom"
import { observer } from "mobx-react-lite"
import validatorjs from 'validatorjs';
import MobxReactForm from 'mobx-react-form';

    const fields = [{
      name: 'email',
      label: 'Email',
      placeholder: 'Email',
      rules: 'required|email|string|between:5,25',
      // value: user.email,
    }, … 
    ]

const FormModel = new MobxReactForm({ fields }, { plugins, hooks }); //nothing exception here standard plugins/hooks

const UserForm = observer(({open, onClose, object}) => {  //My component…object has fields with names email…

  FormModel.$("email").set(object.email); //This works fine if I replace object.email with "foo" 

  return (<MobxInput field={FormModel.$("email")} fullWidth />);
});

export default UserForm;

是的,我检查过该对象是否具有适当的字段(它只是从父级传入的裸对象……在这种情况下甚至不是可观察对象)。

我的第一种方法是简单地将所有内容放入 UserForm 并简单地填充对象字段中的值,但是当我这样做时,输入在结果表单中不起作用(我怀疑 mobx 正在尝试观察创建的对象在那个观察者里面,那是行不通的)。

问题是我有时需要使用相同的表单来处理由我的用户存储中的用户对象提供的数据,有时需要使用空白值来创建新用户,而我现在对如何执行此操作有点困惑。

首先,你不能那样做:

const UserForm = observer(({open, onClose, object}) => {
  // This won't really work very well
  FormModel.$("email").set(object.email);

  return (<MobxInput field={FormModel.$("email")} fullWidth />);
});

因为每次更改输入中的值时,整个 UserForm 组件也会重新呈现(因为它观察到刚刚更改的 FormModel.$("email") 值)并且当它重新呈现时,您会立即将新值更改为旧值来自 object 的值。我不确定你为什么会收到 maxdepth 错误,但在某些情况下,你甚至可能会看到无限循环。在 render 中修改任何类似的东西通常是一种不好的做法。您至少需要使用 useEffect 或类似的东西。

I can't modify observed objects outside of an action

发生这种情况是因为默认情况下您需要在操作内执行所有更改。如果你不喜欢它,你可以配置它:

import { configure } from "mobx"

configure({
    enforceActions: "never",
})

但最好坚持使用它,它可能会捕获一些不需要的行为。

我已经快速 Codesandbox example 使用了您的一些代码,它展示了如何制作多个表单并将默认值传递给它们:

const UserForm = observer(({ object }) => {
  const [FormModel] = useState(() => {
    const fields = [
      {
        name: 'email',
        label: 'Email',
        placeholder: 'Email',
        rules: 'required|email|string|between:5,25',
        value: object?.email || ''
      }
    ];

    return new MobxReactForm({ fields }, { plugins });
  });

  return (
    <form onSubmit={FormModel.onSubmit}>
      <input {...FormModel.$('email').bind()} />
      <p style={{ color: 'red' }}>{FormModel.$('email').error}</p>

      <button type="submit">submit</button>
    </form>
  );
});

这只是众多方式中的一种,最终还是要看你需要什么。