如何使用react-hook-forms制作动态watch()/usewatch()

问题描述 投票:0回答:2

我遇到一个问题,我需要从架构生成表单,并且字段相互依赖,例如启用/禁用显示/隐藏等。

我的架构看起来像这样。

  contractorInformation: {
    title: "ContractorInformation",
    type: "object",
    properties: {
      contractorName: {
        title: "Contractor Name",
        type: "string",
        ui: "input",
        constraints: {
          required: true
        }
      },
      contractorFavouriteAnimal: {
        title: "Contractor Favourite Animal",
        type: "string",
        ui: "input",
        constraints: {},
        dependencies: {
          disabled: true,
          watching: "contractorName"
          // //disabled={!fullName || fullName.length === 0 || errors.fullName}
        }
      },
      contractorEmail: {
        title: "Contractor Email",
        type: "string",
        ui: "input",
        constraints: {
          common: 10
        }
      }
    }
  },
  agencyInformation: {
    title: "ContractorInformation",
    type: "object",
    properties: {
      contractorName: {
        title: "Contractor Name",
        type: "string",
        ui: "input",
        constraints: {
          required: true,
          minLength: 3,
          maxLength: 5
        },
        dependencies: {
          disabled: true,
          watching: "agencyName"
          
        }
      }
    }
  }
}

const watchThese = watch()
可以让我观看所有内容,但如果我想将此字段从禁用更改为启用,我可以使用
 <input disabled={!watchThese || watchThese.length === 0 || watchThese.fullName}/>
它有效,但显然是由每个字段触发的。

如何从模式生成动态 watch()/useWatch() 并能够访问启用/禁用输入所需的特定依赖项。

如有任何帮助,我们将不胜感激。

reactjs watch react-hook-form
2个回答
1
投票

为了将来的参考,我通过使用解决了它

export const FormField = () => 

{Object.entries(schema?.actions ?? {}).forEach(([key, value]) => value(watch(key)));

return (<div></div>)}

并更新架构以匹配。


0
投票

useWatch()
的动态支持已被请求,并且仍然是功能待定。同时,我的解决办法是在
watch()
中使用
useMemo()
,如下例所示:

// dynamicFieldNames is a variable that changes with state, either using useMemo() or useState(). 
// In this case, I'll use useMemo()

// in this example I want to watch the fields that aren't ignored. 

const dynamicFieldNames = useMemo(() => fields.reduce((fieldNames, field) => {
    if(!field.ignore) return fieldNames;
    const fieldName = `quantity__${field.id}`;
    return [...fieldNames, fieldName];
}, []), [fields]);

const watchedValues = useMemo(() => watch(dynamicFieldNames), [dynamicFieldNames]);

您甚至可以为此创建一个简单的自定义挂钩,并将

watch()
作为参数传递,或者使用
useFormContext()
:

获取它
import { useMemo } from 'react';

import { useFormContext } from 'react-hook-form';

const useDynamicWatch = (dynamicFieldNames: string[]): any[] => {
  const { watch } = useFormContext();
  const watchedValues: any[] = useMemo(() => watch(dynamicFieldNames), [dynamicFieldNames]);
  return watchedValues;
};

export default useDynamicWatch; 

重构第一个示例:

const dynamicFieldNames = useMemo(() => fields.reduce((fieldNames, field) => {
    if(!field.ignore) return fieldNames;
    const fieldName = `quantity__${field.id}`;
    return [...fieldNames, fieldName];
}, []), [fields]);

const watchedValues = useDynamicWatch(dynamicFieldNames);
© www.soinside.com 2019 - 2024. All rights reserved.