Javascript 使用Formik更新模糊上的材质UI文本字段(React)
我目前正在呈现一个可编辑表,允许用户一次批量编辑多个用户信息(参见图)。我正在使用MaterialUI的Javascript 使用Formik更新模糊上的材质UI文本字段(React),javascript,reactjs,typescript,material-ui,formik,Javascript,Reactjs,Typescript,Material Ui,Formik,我目前正在呈现一个可编辑表,允许用户一次批量编辑多个用户信息(参见图)。我正在使用MaterialUI的和Formik来处理表单的提交和状态 我正试图: 保持的值与Formik的状态同步 每当我删除一行时(当单击x时),以反映整个表中的更改 该表通常由大约266个输入字段组成。使用onChange事件会带来严重的性能问题。因此,我必须应用几个组件包装和记忆,以防止每次更改单个输入时所有输入字段都重新呈现 我已经成功地完成了这项工作(几乎以一种良好的性能方式),除了删除一行之外。旧的价值似乎仍然
和Formik来处理表单的提交和状态
我正试图:
的值与Formik的状态同步onChange
事件会带来严重的性能问题。因此,我必须应用几个组件包装和记忆,以防止每次更改单个输入时所有输入字段都重新呈现
我已经成功地完成了这项工作(几乎以一种良好的性能方式),除了删除一行之外。旧的价值似乎仍然存在,而Formik的价值确实发生了变化
问题似乎在于
的defaultValue
和value
属性如何工作
value
属性似乎创建了一个受控组件,并将一一反映您在其中传递的任何值。我已经尝试将Formik的字段。value
直接设置到字段中。不幸的是,该值不会更新该字段,因为我目前正在使用onBlur事件来更新它(并且永远不会显示更改)。如果我使用onChange,一切都会正常工作,除了性能是垃圾,因为它会更新所有字段
另一方面,defaultValue
使组件不受控制。尽管如此,我仍然可以编辑该值,甚至可以更新Formik的状态onBlur
!。有一个问题,尽管。。。每当我删除一行时,
中的值不会更新(但Formik会反映更改)
似乎在
组件内部正在进行一些缓存,因为我尝试记录字段的值,这是我当前传递给defaultValue
的值,并且正在显示更改
我也试过:
- 修补
和defaultValue
value
- 设置一个
hook作为Formik值和组件值之间的中间人useState
- 删除备忘录
- 手动实现了备忘录比较
以下是我当前使用的文本字段: FormText
import React,{memo}来自“React”;
从'formik'导入{useField};
从“@material ui/core/TextField”导入TextField;
从“../../../Fields/TextField/TextField definitions”导入{TextProps};
类型ComponentProps=TextProps&{
useBlur?:布尔值;
errorMessage:字符串|未定义;
};
导出常量组件:React.FC=memo(props=>{
常数{
类名,
名称
标签,
占位符,
必修的,
使用模糊,
错误,
错误消息,
一旦改变,
安布尔,
价值
}=道具;
//我们包装它,这样我们就不会阻塞堆堆栈!
//大大提高了性能
// https://medium.com/trabe/react-syntheticevent-reuse-889cd52981b6
常数fireBlur=(e:any)=>{
//反应除去
e、 坚持();
window.setTimeout(()=>{
if(onBlur){
安布尔(e);
}
}, 0);
};
const setInnerState=(e:React.ChangeEvent)=>{};
常量fireChange=(e:React.ChangeEvent)=>{
e、 坚持();
国家(e);
window.setTimeout(()=>{
if(onChange){
onChange(e);
}
}, 0);
};
返回(
);
});
导出常量SchonText:React.FC=props=>{
const[field,meta]=useField(props.name);
const hasError=!!meta.error&&!!meta.toucted;
返回(
);
};
导出默认SchonText;
以下是使用它的组件:表格行
import React,{memo}来自“React”;
从“@material ui/core”导入{TableRow、TableCell、makeStyles};
从“@material ui/icons”导入{Close};
进口{
FormText,
FormSelect,
FormTextArea,
按钮
}来自“../../../../../../../../components”;
从“../../../../../../graphql/types”导入{Student,Gender};
从“../../../../../../components/Fields/Select/Select definitions”导入{SelectOption};
类型BulkAddTableRowProps={
学生:学生;
指标:数量;
deleteStudent:(索引:编号)=>无效;
};
const useStyles=makeStyles(主题=>({
根目录:{
填充:`0px`,
},
}));
const selectOptions:SelectOption[]=[
{
标签:“M”,
价值观:性别,男性,
},
{
标签:“F”,
价值观:性别,女性,
},
];
常量组件:React.FC=props=>{
常量样式=使用样式();
const{student,index}=props;
constDeleteStudent=()=>props.deleteStudent(索引);
返回(
{index+1}
);
};
函数应该保持不变(
prevProps:BulkAddTableRowProps,
新道具:BulkAddTableRowProps,
):布尔值{
const prevStudent=prevProps.student;
const newStudent=newProps.student;
const isNameTheSame=Object.keys(prevStudent.name).every(key=>{
返回prevStudent.name[key]==newStudent.name[key];
});
const isStudentTheSame=对象.键(prevStudent)
.filter(x=>x!=='name')
.every(key=>prevStudent[key]==newStudent[key]);
返回(
isNameTheSame&&isStudentTheSame&&prevProps.index===newProps.index
);
}
导出常量BulkAddTableRow=备注(组件,应保持相同);
导出默认BulkAddTableRow;
StudentBulkTableView
<BulkAddTableRow
key={`${student.name}-${index}`}
<BulkAddTableRow
key={`${student.name.firstName}-${student.name.lastName}`}