问题描述
我正在使用 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 错误,但在某些情况下甚至可能会出现无限循环。在渲染中修改任何类似的东西通常是一种不好的做法。您至少需要使用 useEffect
或类似的东西。
我无法修改动作之外的观察对象
发生这种情况是因为默认情况下您需要在操作中进行所有更改。如果你不喜欢它,你可以配置它:
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>
);
});
这只是众多方法中的一种,这一切都取决于您最终需要什么。