Javascript 识别在Formik FieldArray中已删除(创建和修改)的项目
想知道Formik是否有一个本机解决方案来识别表单中Javascript 识别在Formik FieldArray中已删除(创建和修改)的项目,javascript,reactjs,formik,Javascript,Reactjs,Formik,想知道Formik是否有一个本机解决方案来识别表单中FieldArray的添加和删除(以及更新) 我这里有沙盒上的代码(基于原始的Formik数组示例@) 还有这里的相关部分: 定义了3个朋友的初始状态,我如何在我的onSubmithandler中知道哪一个被修改、删除、更新 import React from "react"; import { Formik, Field, Form, ErrorMessage, FieldArray } from "formik"; const initi
FieldArray
的添加和删除(以及更新)
我这里有沙盒上的代码(基于原始的Formik数组示例@)
还有这里的相关部分:
定义了3个朋友的初始状态
,我如何在我的onSubmithandler
中知道哪一个被修改、删除、更新
import React from "react";
import { Formik, Field, Form, ErrorMessage, FieldArray } from "formik";
const initialValues = {
friends: [
{
name: "Friend_A",
email: "email_A@somewhere.com"
},
{
name: "Friend_B",
email: "email_B@somewhere.com"
},
{
name: "Friend_C",
email: "email_C@somewhere.com"
}
]
};
const mySubmit = values => console.log();
const SignIn = () => (
<div>
<h1>Invite friends</h1>
<Formik
initialValues={initialValues}
onSubmit={values => {
var itemRemoved = values.GetItemRemoveFromArray; // This is what I'm looking for
console.log(itemRemoved);
// Would print Friend_A
var itemAdded = values.GetItemAddedFromArray; // This is what I'm looking for
console.log(itemAdded);
// Would print New_Friend
var itemUpdated = values.GetItemUpdatedInArray; // This is what I'm looking for
console.log(itemUpdated);
// Would print Friend_C
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
}, 500);
}}
render={({ values }) => (
<Form>
<FieldArray
name="friends"
render={({ insert, remove, push }) => (
<div>
{values.friends.length > 0 &&
values.friends.map((friend, index) => (
<div className="row" key={index}>
<div className="col">
<label htmlFor={`friends.${index}.name`}>Name</label>
<Field
name={`friends.${index}.name`}
placeholder="Jane Doe"
type="text"
/>
<ErrorMessage
name={`friends.${index}.name`}
component="div"
className="field-error"
/>
</div>
<div className="col">
<label htmlFor={`friends.${index}.email`}>Email</label>
<Field
name={`friends.${index}.email`}
placeholder="jane@acme.com"
type="email"
/>
<ErrorMessage
name={`friends.${index}.name`}
component="div"
className="field-error"
/>
</div>
<div className="col">
<button
type="button"
className="secondary"
onClick={() => remove(index)}
>
X
</button>
</div>
</div>
))}
<button
type="button"
className="secondary"
onClick={() => push({ name: "", email: "" })}
>
Add Friend
</button>
</div>
)}
/>
<button type="submit">Invite</button>
</Form>
)}
/>
</div>
);
export default SignIn;
从“React”导入React;
从“Formik”导入{Formik,Field,Form,ErrorMessage,FieldArray};
常量初始值={
朋友们:[
{
姓名:“朋友A”,
电子邮件:“电子邮件_A@somewhere.com"
},
{
姓名:“朋友”,
电子邮件:“电子邮件_B@somewhere.com"
},
{
姓名:“朋友”,
电子邮件:“电子邮件_C@somewhere.com"
}
]
};
const mySubmit=values=>console.log();
常量符号=()=>(
邀请朋友
{
var itemRemoved=values.GetItemRemoveFromArray;//这就是我要找的
console.log(itemRemoved);
//我会把你的朋友打印出来吗
var itemAdded=values.GetItemAddedFromArray;//这就是我要找的
console.log(itemsadded);
//我会把新朋友打印出来
var itemUpdated=values.GetItemUpdatedInArray;//这就是我要找的
console.log(项目更新);
//我会打印Friend_C
设置超时(()=>{
警报(JSON.stringify(值,null,2));
}, 500);
}}
render={({values})=>(
(
{values.friends.length>0&&
values.friends.map((friends,index)=>(
名称
电子邮件
删除(索引)}
>
X
))}
推送({name:,email:})}
>
加朋友
)}
/>
邀请
)}
/>
);
导出默认签名;
因此,如果与上述用户一起,您可以选择:
这一点是为了尽量减少对后端的rest调用,以创建/更新实体/链接,而且在调用
remove(索引)之前,我真的不想在remove按钮的onClick
处理程序中编写我自己的“次要状态”处理程序由Formik提供,用于跟踪需要从数据库中删除的内容。它没有内置在Formik中,但在javascript中并不难做到
首先,要了解Formik克隆了您提供给initialValues
的对象。因此,在onSubmit
中,将最终值与原始对象进行比较
传入数据:
const initialFriends = [
{
name: "Friend_A",
email: "email_A@somewhere.com"
},
{
name: "Friend_B",
email: "email_B@somewhere.com"
},
{
name: "Friend_C",
email: "email_C@somewhere.com"
}
];
const initialValues = { friends: initialFriends };
修改的Formik声明:
<Formik initialValues={initialValues}
...
onSubmit={values => {
const { added, deleted, changed } = addDeleteChange(
initialFriends,
values.friends
);
setTimeout(() => {
alert(
"Added: " + JSON.stringify(Object.fromEntries(added.entries()))
);
alert(
"Deleted: " + JSON.stringify(Object.fromEntries(deleted.entries()))
);
alert(
"Changed:" + JSON.stringify(Object.fromEntries(changed.entries()))
);
alert(JSON.stringify(values, null, 2));
}, 500);
}}
...
注意:如果您更改朋友的姓名,则会显示为删除原始朋友和添加新朋友。
一个更健壮的解决方案是为每个朋友添加一个(隐藏的)“id”字段。然后将比较id,而不是比较名称。
这需要在添加每个朋友时生成一个新id
function partition(array, filter) {
let pass = [],
fail = [];
array.forEach(e => (filter(e) ? pass : fail).push(e));
return [pass, fail];
}
const addDeleteChange = (in1, out1) => {
let inMap = new Map(in1.map(f => [f.name, f]));
let outMap = new Map(out1.map(f => [f.name, f]));
let inNames = new Set(inMap.keys());
let outNames = new Set(outMap.keys());
let [kept, added] = partition(out1, f => inNames.has(f.name));
let deleted = in1.filter(f => !outNames.has(f.name));
//alert(JSON.stringify(Object.fromEntries(deleted.entries())));
let changed = kept.filter(f => f.email !== inMap.get(f.name).email);
//alert(JSON.stringify(Object.fromEntries(changed.entries())));
return { added: added, deleted: deleted, changed: changed };
};