react-hook-form。 useFieldArray Controller 必填,报错自动获取较多疑问记录

这篇具有很好参考价值的文章主要介绍了react-hook-form。 useFieldArray Controller 必填,报错自动获取较多疑问记录。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

背景

动态多个数据Controller包裹时候,原生html标签input可以add时候自动获取焦点,聚焦到最近不符合要求的元素上面

  • matiral的TextField同样可以
  • 可是x-date-pickers/DatePicker不可以❌
是什么原因呢,内部提供foucs??属性才可以,还是?

暂时记录下,问题还未解决

input图:

react-hook-form。 useFieldArray Controller 必填,报错自动获取较多疑问记录,代码片段,前端,react.js,react-hook-form

input代码:

直接用controller的field,add时候就可以给最前面一个没有有效输入的input获取焦点

<input
key={field.id} // important to include key with field's id
{...field}
/>
TextField图:

react-hook-form。 useFieldArray Controller 必填,报错自动获取较多疑问记录,代码片段,前端,react.js,react-hook-form

TestField代码:

必须用register,controller的field无效(没有add自动获取最前面无效输入的表单)

<TextField
                                    {...field}
                                    label="Username"
                                    variant="outlined"
                                    {...register(`test.${index}.value`, {
                                        required: {
                                            value: true,
                                            message: "required"
                                        }
                                    })}
                                />
x-data-picker

用controller的fields或者regiter都无效

完整代码
import { useForm, Controller, useFieldArray } from "react-hook-form";
import { TextField } from "@mui/material";
import { useEffect } from "react"
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
function Form() {
    const { register, setFocus, control, handleSubmit, formState: { errors, isDirty }, formState } = useForm();
    const { fields, append, prepend, remove, swap, move, insert } = useFieldArray({
        control, // control props comes from useForm (optional: if you are using FormContext)
        name: "test", // unique name for your Field Array
        defaultValue: {
            test: [
                {
                    value: 100
                }
            ]
        }
    });

    const onSubmit = (data) => {
        console.log("data", data);
    };
    // console.log("errors", errors)
    useEffect(() => {
        // const firstError = Object.keys(errors).reduce((field, a) => {
        //     return !!errors[field] ? field : a;
        // }, null);
        // console.log("firstError", firstError)
        // if (firstError) {
        //     setFocus(firstError);
        // }
        // console.log("errors.test[0]", formState.errors)
        // if (errors.test && errors.test[0]?.value?.ref) {
        //     console.log(" errors.test[0].value.ref", errors.test[0].value.ref)
        //     //errors.test[0].value.ref.focus()
        //     setFocus(`test.${0}.value`)
        // }

    }, [errors, formState]);
    const appendfile = () => {
        append({
            value: ""
        })
    }

    return (
        <form onSubmit={handleSubmit(onSubmit)}>
            <p>{String(isDirty)}</p>
            {fields.map((field, index) => (
                <div key={field.id}>
                    {/* <input
                        key={field.id} // important to include key with field's id
                        {...register(`test.${index}.value`, {
                            required: {
                                value: true,
                                message: "required"
                            }
                        })}
                    /> */}

                    {/* <TextField
                        key={field.id} // important to include key with field's id
                        {...register(`test.${index}.value`, {
                            required: {
                                value: true,
                                message: "required"
                            }
                        })}
                    /> */}


                    <Controller
                        name={`test.${index}.value`}
                        control={control}
                        defaultValue=""
                        rules={{
                            required: {
                                value: true,
                                message: "required"
                            }
                        }}
                        errors={isDirty && errors.test && errors.test[index] && errors.test[index].value.message ? true : false}
                        render={({ field }) => {
                            console.log("field", field)
                            //     required: {
                            //         value: true,
                            //         message: "required"
                            //     }
                            // }))

                            return (
                                //一,可以自动获取焦点

                                // <TextField
                                //     {...field}
                                //     label="Username"
                                //     variant="outlined"
                                //     {...register(`test.${index}.value`, {
                                //         required: {
                                //             value: true,
                                //             message: "required"
                                //         }
                                //     })}
                                // />
                                //二,可以自动获取焦点
                                // <input
                                //     key={field.id} // important to include key with field's id
                                //     {...field}
                                // />
                                //三,可以自动获取焦点
                                // < LocalizationProvider dateAdapter={AdapterDayjs} >
                                //     <DatePicker
                                //         {...field}
                                //         {...register(`test.${index}.value`, {
                                //             required: {
                                //                 value: true,
                                //                 message: "required"
                                //             }
                                //         })}
                                //     />
                                // </LocalizationProvider>
                            )
                        }}
                    />


                </div>
            ))}
            <div>
                <button onClick={appendfile}>add</button>
            </div>

            <div>
                <input type="submit" />
            </div>
        </form>
    );
}

export default Form;
append 后不自动focus

lib版本:7.47.0 ,一下代码window 谷歌可行,苹果谷歌不可行

append({
            value: "",
            time: null
        }, {
            shouldFocus: false,
})
isduty在提交后,依旧是true,如何解决:
 React.useEffect(() => {
    if (isSubmitted) {
      reset({}, { keepValues: true });
    }
  }, [isSubmitted, reset]);

代码:React Hook Form - useForm Template (forked) - CodeSandbox

注意必须通过handleSubmit(handler) handleSubmit函数来包裹提交函数

参考:

isDirty is not set to false after successful submission · Issue #3097 · react-hook-form/react-hook-form · GitHub

bug:与x-data-grid配合使用,remove出行问题,正常删除

错误例子:https://codesandbox.io/s/laughing-snyder-t8cmsx?file=/demo.tsx 

修复例子:https://codesandbox.io/s/strange-surf-cd13lp?file=/demo.tsx:1070-1083

原因是传递fields时候x-data-grid 同样会修改这个数据导致两边冲突,所以不要直接床底fields,而是克隆一份,同时注册input时候要先判断getValues("test")和列对应的id的元素是否存在,不存在return null,不再执行register

完整代码:文章来源地址https://www.toymoban.com/news/detail-737360.html

import * as React from "react";
import { v4 as uuid } from "uuid";

import Box from "@mui/material/Box";
import { DataGrid, GridColDef, GridCellParams } from "@mui/x-data-grid";

import { useFieldArray, useForm } from "react-hook-form";
import { Button } from "@mui/material";

export default function DataGridProDemo() {
  const { control, register, getValues, handleSubmit, reset, watch } = useForm({
    defaultValues: {
      test: []
    }
  });
  const testWatcher = watch("test");
  const { fields, append, remove } = useFieldArray({
    name: "test",
    control: control
  });

  console.log(
    "testWatcher",
    JSON.stringify(testWatcher),
    "test",
    JSON.stringify(fields)
  );

  const data = getValues("test") || [];

  const getIndexByRow = (arr: { id: string }[], id: string | number) => {
    return arr ? arr.findIndex((r) => r.id === id) : -1;
  };

  const columns: GridColDef = [
    {
      field: "name",
      headerName: "Name",
      flex: 1,
      width: 100,
      renderCell: (params: GridCellParams<any>) => {
        const index = getIndexByRow(getValues("test"), params.id);
        if (index === -1) {
          return null;
        }
        return <input {...register(`test.${index}.name`)} />;
      }
    },
    {
      field: "age",
      headerName: "Age",
      flex: 1,
      width: 100,
      renderCell: (params: GridCellParams<any>) => {
        const index = getIndexByRow(getValues("test"), params.id);
        if (index === -1) {
          return null;
        }
        return <input {...register(`test.${index}.age`)} />;
      }
    },
    {
      field: "id",
      headerName: "Action",
      align: "center",
      headerAlign: "center",
      flex: 1,
      width: 100,
      renderCell: (params: GridCellParams<any>) => {
        const index = getIndexByRow(getValues("test"), params.id);
        if (index === -1) {
          return null;
        }
        return (
          <Button
            onClick={() => {
              remove(index);
            }}
          >
            delete
          </Button>
        );
      }
    }
  ];

  const cloned = data.map(({ id, age, name, dataType }) => ({
    id,
    age,
    name,
    dataType
  }));
  console.log({ cloned });

  return (
    <>
      <Button
        onClick={() => {
          append({ id: uuid(), name: "", dataType: "" });
        }}
      >
        Add
      </Button>
      <Box sx={{ height: 520, width: "100%" }}>
        <DataGrid rows={cloned} columns={columns} pageSize={5} />
      </Box>
    </>
  );
}

到了这里,关于react-hook-form。 useFieldArray Controller 必填,报错自动获取较多疑问记录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【React】React Hooks解析

    React 16.8 + 为什么需要Hook? Hook是 React 16.8 的新增特性,它可以让我们在不编写class的情况下使用state以及其他的React特性(比如生命周期) 我们先来思考一下class组件相对于函数式组件有什么优势?比较常见的是下面的优势: class组件可以 定义自己的state ,用来 保存组件自己内

    2024年02月11日
    浏览(55)
  • React hook 10种常见 Hook

    React官网是这么介绍的: Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。 完全可选的 你无需重写任何已有代码就可以在一些组件中尝试 Hook。但是如果你不想,你不必现在就去学习或使用 Hook。 100% 向后兼容的 Hook 不包含任何

    2024年02月10日
    浏览(37)
  • React的hooks---自定义hooks

    通过自定义 Hook,可以将组件逻辑提取到可重用的函数中,在 Hook 特性之前,React 中有两种流行的方式来共享组件之间的状态逻辑: render props 和 高阶组件 ,但此类解决方案会导致组件树的层级冗余等问题。而自定义 Hook 的使用可以很好的解决此类问题 自定义 Hook 是一个函数

    2024年02月15日
    浏览(32)
  • 【《React Hooks实战》——指导你使用hook开发性能优秀可复用性高的React组件】

    使用React Hooks后,你很快就会发现,代码变得更具有组织性且更易于维护。React Hooks是旨在为用户提供跨组件的重用功能和共享功能的JavaScript函数。利用React Hooks, 可以将组件分成多个函数、管理状态和副作用,并且不必声明类即可调用React内置的功能。而且,上述所有的操作

    2024年02月14日
    浏览(36)
  • 带你看懂 Vue Hook和React Hook

    react Hook React Hook 是 React 16.8 版本引入的一项新特性,它能够让函数组件拥有类组件中的状态(state)和生命周期方法(lifecycle methods)等功能。React Hook 包括了多个钩子函数(hook functions),如 useState、useEffect、useContext 等,在函数组件中使用这些钩子函数可以实现一系列常见的功能,

    2023年04月26日
    浏览(40)
  • 【实战】 React 与 Hook 应用:实现项目列表 —— React17+React Hook+TS4 最佳实践,仿 Jira 企业级项目(二)

    学习内容来源:React + React Hook + TS 最佳实践-慕课网 相对原教程,我在学习开始时(2023.03)采用的是当前最新版本: 项 版本 react react-dom ^18.2.0 react-router react-router-dom ^6.11.2 antd ^4.24.8 @commitlint/cli @commitlint/config-conventional ^17.4.4 eslint-config-prettier ^8.6.0 husky ^8.0.3 lint-staged ^13.1.2 p

    2024年02月09日
    浏览(56)
  • react hook: useReducer

    useReducer 相当于 Vuex 中的 store 和 mutations 的结合。 useReducer 更适用于处理复杂的状态逻辑,尤其是当状态之间存在关联,或者需要多个状态同时更新时。可以让我们的代码具有更好的可读性、可维护性、可预测性。 const [state, dispatch] = useReducer(reducer, initialArg, init?) 在组件的顶

    2024年03月15日
    浏览(38)
  • countDown+react+hook

    道阻且长,行而不辍,未来可期 知识点一: new Date().getTime() 可以得到得到1970年01月1日0点零分以来的毫秒数。单位是毫秒 知识点二、 为什么使用 requestAnimationFrame 来写定时器呢? 答:当页面离开或切换到其他标签页时,requestAnimationFrame 中的代码将不再执行。 详解:因为

    2024年02月11日
    浏览(28)
  • React笔记(五)hook

    一、函数组件 1、函数组件的创建 函数组件:使用JS的函数(或箭头函数)创建的组件称为函数组件,函数组件有如下约定 函数名称必须以大写字母开头 函数组件必须有返回值,返回JSX表达式 渲染函数组件:用函数名作为组件标签名 组件名称可以是单标签也可以是双标签

    2024年02月10日
    浏览(38)
  • React Hooks 基本使用

    class 组件如果业务复杂,很难拆分和重构,很难测试;相同业务逻辑分散到各个方法中,逻辑混乱 逻辑复用像 HOC 、 Render Props ,不易理解,学习成本高 React 提倡函数式编程,函数更易拆分,更易测试 但是函数组件太简单,为了增强函数组件的功能,媲美 class 组件: 函数组

    2024年01月21日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包