在自定义编辑组件中对材料表Formik验证做出反应

时间:2019-12-02 15:58:08

标签: reactjs formik material-table

我正在使用react-material-table。 我正在尝试验证行编辑。

对于“本机”材料列,一切正常。 但是我必须为一列使用自定义editComponent来呈现自动完成功能。

{
      title: "test",
      field: "foo",
      editComponent: (props) => {


        return (
          <div>
            <Autocomplete

              onChange={(e, v) => this.handleFooChange(props.rowData.id, v)}
              //onChange={(e,v) => props.onChange(v)}
              id="people-company"
              options={[{ id: 1, name: "bar" }, { id: 2, name: "foo" }]}
              getOptionLabel={option => option.name}

              value={props.rowData.foo}
              filterSelectedOptions
              renderInput={params => (
                <TextField
                  {...params}
                  variant="outlined"
                  label="company"
                  placeholder="company"
                  margin="normal"
                  fullWidth
                />
              )}
            />
          </div>
        );
      },

我的MaterialTable定义了EditRow和EditField

    const FormikMTInput = props => {

  return (
    <Field name={props.columnDef.field}>
      {({ field, form, meta }) => {
        const { name } = field;
        const { errors, setFieldValue } = form;
        //console.log("ShowError", errors);
        const showError = !!getIn(errors, name);

        return (
          <div>
            <MTableEditField
              {...props}
              {...field}
              error={showError}
              onChange={newValue => setFieldValue(name, newValue)}
            />
            {errors[field.name] && (
              <div style={{ color: "#f44336" }}>{errors[field.name]}</div>
            )}
          </div>
        );
      }}
    </Field>
  );
};

const MuiTableEditRow = ({ onEditingApproved, ...props }) => {

  return(
  <Formik

    validate={values => {
      const errors = {};
      if (!values.name) {
        errors.name = "Required";
      }
      if (!values.foo) {
        errors.foo = "Required";
      }

      return errors;
    }}
    initialValues={props.data}
    onSubmit={values => {
      if (values) {
        if (values.name.length > 2 && values.foo)
          onEditingApproved(props.mode, values, props.data);
      }
    }}
    render={({ submitForm }) => (
      <MTableEditRow {...props} onEditingApproved={submitForm} />
    )}
  />
)};
  <MaterialTable
      title="Editable Preview"
      columns={this.state.columns}
      data={this.state.data}
      components={{
        EditRow: MuiTableEditRow,
        EditField: FormikMTInput
      }}
    />

FormikMTInput在“默认”列上触发良好。被覆盖的editComponent并非如此。如何将错误传递给此列?

sandbox

1 个答案:

答案 0 :(得分:0)

问题是,当前值与rowData值不同。 因此,在自动完成功能中将value={props.rowData.foo}更改为value={props.value},以获得正确的值。以前,rowData从未在编辑时更改过,因为在保存之前该行仍然具有数据。

此外,您应该将已经转换的值传递给onChange函数,而不是这样的事件:onChange={v => props.onChange(v.target.value)}

if (!id || id === undefined) return;等于if (!id) return;,因为!id对于未定义返回true。

最后但并非最不重要的一点是,您正在

中更改状态数据
var myData = this.state.data;
   myData.forEach(d => {
      if (d.id === id) {
      d.foo = v;
    }
  });

这是不行的。更改为:

handleFooChange(id, v) {
    if (!id) return;
    const myData = this.state.data.map(d => d.id === id ? {...d, foo: v} : d);
    this.setState({ data: myData });
}