React 钩子形式,从简化数组设置默认值不会填充,但手动输入相同的对象会

如何解决React 钩子形式,从简化数组设置默认值不会填充,但手动输入相同的对象会

我正在使用 react hooks 表单,并且我正在尝试设置通过映射数组并输出表单中的输入来输出的表单的认值。我已将数组简化为像 {name0:"fijs",name1:"3838"...} 这样的对象,如果我手动将其传递到认值,它会映射到我的输入并填充它们。但是,如果我从执行 reduce 函数的变量中输入它们,它不会填充它。我认为这是因为在第一次渲染时它是未定义的。我试过使用 useEffect,但没有用,所以我被卡住了。

这是我正在处理的代码的一部分

const test = formState?.reduce((obj,item,idx) => {
    return { ...obj,[`${item.name}${idx}`]: "fdsjfs" };
  },{});

  const { register,handleSubmit,errors } = useForm({
    defaultValues: test,});

  console.log(test);

这就是整件事

import { useQuery,gql,useMutation } from "@apollo/client";
import { useEffect,useState } from "react";
import { v4 as uuidv4 } from "uuid";
import { useForm } from "react-hook-form";

const INPUT_VALUES = gql`
  query GetInputValues {
    allFormInputVals {
      data {
        name
        _id
        type
      }
    }
  }
`;

const ADD_INPUT_VALUES = gql`
  mutation AddInputValues(
    $name: String!
    $type: String!
    $index: Int!
    $ID: ID!
  ) {
    createFormInputVal(
      data: {
        name: $name
        type: $type
        index: $index
        formRoot: { connect: $ID }
      }
    ) {
      name
    }
  }
`;

const Home = () => {
  const blankFormInput = {
    __typename: "FormInputVal",name: "test",_id: uuidv4(),type: "text",};
  const [formState,setFormState] = useState([blankFormInput]);
  const [formStateVals,setFormStateVals] = useState(undefined);

  const { loading,error,data } = useQuery(INPUT_VALUES);

  const [createFormInputVal,{ data: createInputData }] = useMutation(
    ADD_INPUT_VALUES
  );

  useEffect(() => {
    setFormState(data?.allFormInputVals?.data);
  },[data]);

  const test = formState?.reduce((obj,});

  console.log(test);

  const onSubmit = (data) => console.log(data);
  console.log(errors);

  const addInput = async () => {
    const blanktext = {
      __typename: "FormInputVal",name: "Product Image",};
    setFormState([...formState,{ ...blanktext }]);
    console.log(formState);
    const res = await createFormInputVal({
      variables: {
        name: "test",index: 0,ID: "291541554941657608",},}).catch(console.error);
    console.log(res);
  };

  if (loading) return <p>Loading...</p>;

  if (error) return <p>Error: {error.message}</p>;

  return (
    <>
      <form onSubmit={handleSubmit(onSubmit)}>
        <input type="button" value="Add Form Input" onClick={addInput} />
        {formState?.map((val,idx) => {
          const nameId = `name${idx}`;
          const typeId = `type-${idx}`;
          return (
            <div key={val._id}>
              {val.type === "text" && (
                <>
                  <label htmlFor={nameId}>{`${val.name} #${idx + 1}`}</label>

                  <input
                    type="text"
                    name={nameId}
                    id={nameId}
                    className={val.type}
                    ref={register()}
                  />
                  {/* <label htmlFor={typeId}>{`Type #${idx + 1}`}</label>

                  <select name={typeId} id={typeId} className={val.type}>
                    {data.allFormInputVals.data.map((item) => {
                      return (
                        <option key={item._id} value={item.type}>
                          {item.type}
                        </option>
                      );
                    })}
                  </select> */}
                </>
              )}
            </div>
          );
        })}
        <button type="submit">Save Form</button>
      </form>
    </>
  );
};

export default Home;

更新:我已经尝试通过 api 重置 useEffect,我认为这是解决方案,但仍然没有骰子。

const { register,errors,reset } = useForm();

useEffect(() => {
    const result = test; // result: { firstName: 'test',lastName: 'test2' }
    reset(result); // asynchronously reset your form values
  },[reset]);

更新:我将表单抽象为它自己的组件,但它仍然不起作用。

Form.js

import { useEffect,useState } from "react";
import { useForm } from "react-hook-form";
import { useQuery,useMutation } from "@apollo/client";
import { v4 as uuidv4 } from "uuid";

const ADD_INPUT_VALUES = gql`
  mutation AddInputValues(
    $name: String!
    $type: String!
    $index: Int!
    $ID: ID!
  ) {
    createFormInputVal(
      data: {
        name: $name
        type: $type
        index: $index
        formRoot: { connect: $ID }
      }
    ) {
      name
    }
  }
`;

export default function Form({ formState,setFormState }) {
  const test = formState?.reduce((obj,{});

  console.log(test);

  const { register,errors } = useForm({ defaultValues: test });
  const [formStateVals,setFormStateVals] = useState(undefined);

  // console.log(test);

  const onSubmit = (data) => console.log(data);
  console.log(errors);

  const addInput = async () => {
    const blanktext = {
      __typename: "FormInputVal",}).catch(console.error);
    console.log(res);
  };

  const [createFormInputVal,{ data: createInputData }] = useMutation(
    ADD_INPUT_VALUES
  );

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input type="button" value="Add Form Input" onClick={addInput} />
      {formState?.map((val,idx) => {
        const nameId = `name${idx}`;
        const typeId = `type-${idx}`;
        return (
          <div key={val._id}>
            {val.type === "text" && (
              <>
                <label htmlFor={nameId}>{`${val.name} #${idx + 1}`}</label>

                <input
                  type="text"
                  name={nameId}
                  id={nameId}
                  className={val.type}
                  ref={register()}
                />
                {/* <label htmlFor={typeId}>{`Type #${idx + 1}`}</label>

                  <select name={typeId} id={typeId} className={val.type}>
                    {data.allFormInputVals.data.map((item) => {
                      return (
                        <option key={item._id} value={item.type}>
                          {item.type}
                        </option>
                      );
                    })}
                  </select> */}
              </>
            )}
          </div>
        );
      })}
      <button type="submit">Save Form</button>
    </form>
  );
}

index.js

import { useQuery,useState } from "react";
import { v4 as uuidv4 } from "uuid";
import Form from "../components/Form";

const INPUT_VALUES = gql`
  query GetInputValues {
    allFormInputVals {
      data {
        name
        _id
        type
      }
    }
  }
`;

const Home = () => {
  const blankFormInput = {
    __typename: "FormInputVal",setFormState] = useState([blankFormInput]);

  const { loading,data } = useQuery(INPUT_VALUES);

  useEffect(() => {
    const formData = data?.allFormInputVals?.data;
    setFormState(formData);
  },[data]);

  if (loading) return <p>Loading...</p>;

  if (error) return <p>Error: {error.message}</p>;

  return (
    <>
      <Form formState={formState} setFormState={setFormState} />
    </>
  );
};

export default Home;

解决方法

您可以将表单提取到其自己的组件中,并仅在获取数据时呈现它。这样,当您在子组件中使用 String str ; str = str.replaceAll("{"s":[0-9]+,"v":",""); 时,将正确设置默认值。

useForm

如果您不想更改结构,您可以在数据准备好时使用 setValue 设置输入值。

const Home = () => {
  const { loading,error,data } = useQuery(INPUT_VALUES)
  const blankFormInput = {
    __typename: "FormInputVal",name: "test",_id: uuidv4(),type: "text",}
  const [formState,setFormState] = useState([blankFormInput])

  // other code

  if (loading) {
    return <p>Loading...</p>
  }

  return <MyForm defaultValues={formState} />
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?