【问题标题】:MUI + React Hook Form: Fill out TextField value but then can't modify the valueMUI + React Hook Form:填写TextField值但无法修改该值
【发布时间】:2022-10-22 17:29:24
【问题描述】:

我正在使用 MUI + React Hook Form 的组合,所以我创建了一个CustomTextField.tsx 组件来使其工作。

// CustomTextField.tsx
import { TextField } from "@mui/material";

export default function CustomTextField(props: any) {
  return (
    <Controller
      name={props.name}
      control={props.control}
      render={({
        field: { onChange, value },
        fieldState: { error },
        formState
      }) => <TextField onChange={onChange} {...props} />}
    />
  );
}

然后在应用程序/父级,我想要这些步骤:

  1. 获取数据并显示到 TextField。
  2. 修改TextField中的文字
  3. 在 TextField 中提交新值

    这是我的方法:

    //App.tsx
    export default function App() {
      const { control, handleSubmit } = useForm();
      const [fetchedData, setFetchedData] = useState<string>("");
      ...
      return (
    ...
            <CustomTextField
              control={control}
              name="description"
              label="Description"
              type="text"
              variant="outlined"
              value={fetchedData ? fetchedData: ""}     //<-- fetched data is set to value of TextField to display
            />
    ...
      );
    }
    

    使用这种方法,我设法在 TextField UI 上显示 fetchedData,但无法在文本字段上修改该数据。此外,当我提交时,数据与 TextField 上显示的内容不正确

    我为此创建了一个代码框链接:https://codesandbox.io/s/blissful-sanne-x858dx?file=/src/App.tsx:190-1155

    如何显示 fetchedData,还可以修改文本字段中的数据,然后通过 React Hook Form 提交?

【问题讨论】:

  • 我没有看到您的实现的 onChange 事件,您需要 onChange 事件来更改状态,以便可以更新它。
  • 我必须将 onChange 从 Controller 传递给 TextField,所以 React Hook Form 可以工作。我不知道如何使用 onChange 父级别和组件级别

标签: javascript reactjs typescript material-ui react-hook-form


【解决方案1】:

您想要的是有一个文本输入,用户可以在其中键入一个值,但您也可以通过单击“获取数据”按钮在外部设置该值。

您的设置包括相互矛盾的事实来源。该字段的value 设置为data 状态,并且存储在react-hook-form 状态中的值被忽略。

您要做的是在按下按钮时修改react-hook-form 的内部状态。

您可以删除本地状态:

const [data, setData] = useState<string>("");

相反,您可以使用以下表单中的 setValue 辅助函数:

const { control, handleSubmit, setValue } = useForm<FormValues>();

const fetchingData = () => {
  setValue("description", "fetched description Text");
};

在您的CustomTextField 中,确保将输入的value 从表单状态设置为value

render={({
  field: { onChange, value },
  fieldState: { error },
  formState
}) => <CusTextField onChange={onChange} value={value} {...props} />}

Complete Code

【讨论】:

  • 谢谢!这似乎在功能上起作用,但是,TextField 似乎没有获得 :active,因此标签与值文本重叠。你知道如何解决它吗?
  • 有趣的。 react-hook 表单包中可能有一些东西可以处理焦点,但我对这个包不是很熟悉。您可以将ref 向下传递给DOM &lt;input&gt; 元素并在fetchingData() 中调用inputRef.current?.focus()
【解决方案2】:

受上述@Linda 解决方案的启发,我提出了这种方法,它确保功能也适用于 MUI TextField 的样式。

setValue 将传递给自定义 TextField 以设置值。为了保留{...props} 功能,我删除了setValue 道具,然后将其传播到MUI TextField 上。

import { TextField } from "@mui/material"
import { Controller } from "react-hook-form"

export default function CustomTextField(props: any) {
  const propsObj = { ...props }
  delete propsObj.setValue
  return (
    <Controller
      name={props.name}
      control={props.control}
      defaultValue={""}
      render={({
        field: { onChange, value },
        fieldState: { error },
        formState,
      }) => (
        <TextField
          value={value}
          onChange={({ target: { value } }) => {
            onChange(value)
            if (props?.setValue) props.setValue(props.name, value)
          }}
          {...propsObj}
        />
      )}
    />
  )
}

//App.tsx
export default function App(){
  const { control, handleSubmit, setValue } = useForm()
  return (
    ...
    <CustomTextField
      control={control}
      name="description"
      label="Description"
      type="text"
      variant="outlined"
      setValue={setValue}
    />
    ...
  )
}


【讨论】:

    猜你喜欢
    • 2022-12-02
    • 2020-09-24
    • 2022-01-16
    • 2021-10-24
    • 1970-01-01
    • 2020-11-15
    • 2020-11-23
    • 2023-04-09
    • 2022-01-25
    相关资源
    最近更新 更多