0

我正在使用 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 正在尝试观察在该观察者内部创建的对象,并且不起作用)。

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

4

1 回答 1

2

首先,你不能这样做:

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 错误,但在某些情况下,你甚至可能会看到无限循环。在渲染内部修改类似的东西通常是一种不好的做法。useEffect您至少需要使用或类似的东西。

我无法在动作之外修改观察到的对象

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

import { configure } from "mobx"

configure({
    enforceActions: "never",
})

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

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

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>
  );
});

这只是众多方法中的一种,这完全取决于您最终需要什么。

于 2021-07-19T18:35:13.407 回答