Javascript 使用Formik更新模糊上的材质UI文本字段(React)

Javascript 使用Formik更新模糊上的材质UI文本字段(React),javascript,reactjs,typescript,material-ui,formik,Javascript,Reactjs,Typescript,Material Ui,Formik,我目前正在呈现一个可编辑表,允许用户一次批量编辑多个用户信息(参见图)。我正在使用MaterialUI的和Formik来处理表单的提交和状态 我正试图: 保持的值与Formik的状态同步 每当我删除一行时(当单击x时),以反映整个表中的更改 该表通常由大约266个输入字段组成。使用onChange事件会带来严重的性能问题。因此,我必须应用几个组件包装和记忆,以防止每次更改单个输入时所有输入字段都重新呈现 我已经成功地完成了这项工作(几乎以一种良好的性能方式),除了删除一行之外。旧的价值似乎仍然

我目前正在呈现一个可编辑表,允许用户一次批量编辑多个用户信息(参见图)。我正在使用MaterialUI的
和Formik来处理表单的提交和状态

我正试图:

  • 保持
    的值与Formik的状态同步
  • 每当我删除一行时(当单击x时),以反映整个表中的更改
  • 该表通常由大约266个输入字段组成。使用
    onChange
    事件会带来严重的性能问题。因此,我必须应用几个组件包装和记忆,以防止每次更改单个输入时所有输入字段都重新呈现

    我已经成功地完成了这项工作(几乎以一种良好的性能方式),除了删除一行之外。旧的价值似乎仍然存在,而Formik的价值确实发生了变化

    问题似乎在于
    defaultValue
    value
    属性如何工作

    value
    属性似乎创建了一个受控组件,并将一一反映您在其中传递的任何值。我已经尝试将Formik的
    字段。value
    直接设置到字段中。不幸的是,该值不会更新该字段,因为我目前正在使用onBlur事件来更新它(并且永远不会显示更改)。如果我使用onChange,一切都会正常工作,除了性能是垃圾,因为它会更新所有字段

    另一方面,
    defaultValue
    使组件不受控制。尽管如此,我仍然可以编辑该值,甚至可以更新Formik的状态
    onBlur
    !。有一个问题,尽管。。。每当我删除一行时,
    中的值不会更新(但Formik会反映更改)

    似乎在
    组件内部正在进行一些缓存,因为我尝试记录字段的值,这是我当前传递给
    defaultValue
    的值,并且正在显示更改

    我也试过:

    • 修补
      defaultValue
      value
    • 设置一个
      useState
      hook作为Formik值和组件值之间的中间人
    • 删除备忘录
    • 手动实现了备忘录比较
    而且它们似乎都不起作用。。。在这种情况下我该怎么办

    以下是我使用的代码供参考:


    以下是我当前使用的文本字段:

    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}`}