在 react-hook-form 中设置 DatePicker 的值(来自 antd)

Posted

技术标签:

【中文标题】在 react-hook-form 中设置 DatePicker 的值(来自 antd)【英文标题】:Setting the value of DatePicker (from antd) in react-hook-form 【发布时间】:2020-03-08 17:26:57 【问题描述】:

我正在尝试弄清楚如何将 antd 中的 DatePicker 与 react-hook-form 一起使用。

目前,我的尝试是:

import React,  useState, useEffect  from "react";
import ReactDOM from "react-dom";
import useForm from "react-hook-form";
import  withRouter  from "react-router-dom";
import  useStateMachine  from "little-state-machine";
import updateAction from "./updateAction";
import  Input as InputField, Form, Button, DatePicker, Divider, Layout, Typography, Skeleton, Switch, Card, Icon, Avatar  from 'antd';
import Select from "react-select";


const  Content  = Layout 
const  Text, Paragraph  = Typography;
const  Meta  = Card;
const  MonthPicker, RangePicker, WeekPicker  = DatePicker;



  const Team = props => 
    const  register, handleSubmit, setValue, errors  = useForm();
    const [ dueDate, setDate ] = useState(new Date());
    const [indexes, setIndexes] = React.useState([]);
    const [counter, setCounter] = React.useState(0);
    const  action  = useStateMachine(updateAction);
    const onSubit = data => 
      action(data);
      props.history.push("./ProposalBudget");
    ;

    
    // const handleChange = dueDate => setDate(date);
    const handleChange = (e) => 
      setValue("dueDate", e.target.value);
    


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

  const addMilestone = () => 
    setIndexes(prevIndexes => [...prevIndexes, counter]);
    setCounter(prevCounter => prevCounter + 1);
  ;

  const removeMilestone = index => () => 
    setIndexes(prevIndexes => [...prevIndexes.filter(item => item !== index)]);
  ;

  const clearMilestones = () => 
    setIndexes([]);
  ;

  useEffect(() => 
    register( name: dueDate ); // custom register antd input
  , [register]);

注意:我也试过名称:$fieldName.dueDate - 这也不起作用。

  return (
    <div>
        <HeaderBranding />
        <Content
          style=
            background: '#fff',
            padding: 24,
            margin: "auto",
            minHeight: 280,
            width: '70%'
          
        >
        <form onSubmit=handleSubmit(onSubit)>
        
          indexes.map(index => 
            const fieldName = `milestones[$index]`;
            return (
              <fieldset name=fieldName key=fieldName>
                <label>
                  Title:
                  <input
                    type="text"
                    name=`$fieldName.title`
                    ref=register
                  />
                </label>

                <label>
                  Description:
                  <textarea
                    rows=12
                    name=`$fieldName.description`
                    ref=register
                  />
                </label>
                <label>When do you expect to complete this milestone? <br />
                
                  
                <DatePicker 
                  selected= dueDate  
                  // ref=register
                  InputField name=`$fieldName.dueDate` 
                  onChange=handleChange(index)

                  //onChange= handleChange 
                   >
                  <input 
                  type="date" 
                  name=`$fieldName.dueDate` 
                  inputRef=register
                />
                </DatePicker>
              
                </label>
                
                <Button type="danger" style= marginBottom: '20px', float: 'right' onClick=removeMilestone(index)>
                  Remove this Milestone
                </Button>
              </fieldset>
            );
          )

          <Button type="primary" style= marginBottom: '20px' onClick=addMilestone>
            Add a Milestone
          </Button>
          <br />
          <Button type="button" style= marginBottom: '20px' onClick=clearMilestones>
            Clear Milestones
          </Button>
          <input type="submit" value="next - budget" />
        </form>
       </Content>
       
      </div>  
  );
;

export default withRouter(Team);

这会生成一条错误消息:TypeError: Cannot read property 'value' of undefined

setValue 在handleChange 中定义。

我不清楚要使此日期选择器正常运行需要哪些步骤。我需要单独的选择功能吗?

有人知道如何插入这个日期选择器吗?

我也试过了:

const handleChange = (e) => 
      setValue("dueDate", e.target.Date);
    

我已经试过了:

const handleChange = (e) => 
      setValue("dueDate", e.target.date);
    

但每一代都有相同的错误

【问题讨论】:

【参考方案1】:
/* eslint-disable react/prop-types */
import React,  useState  from 'react';
import  DatePicker  from 'antd';
import  Controller  from 'react-hook-form';
import color from '../../assets/theme/color';

import DatePickerContainer from './DatePickerContainer';

function DatePickerAntd(props) 

  const  control, rules, required, title, ...childProps  = props;
  const  name  = childProps;

  const [focus, setFocus] = useState(false);

  const style = 
    backgroundColor: color.white,
    borderColor: color.primary,
    borderRadius: 5,
    marginBottom: '1vh',
    marginTop: '1vh',
  ;

  let styleError;
  if (!focus && props.error) 
    styleError =  borderColor: color.red ;
  

  return (
    <div>
      <Controller
        as=
          <DatePicker
            style= ...style, ...styleError 
            size="large"
            format="DD-MM-YYYY"
            placeholder=props.placeholder || ''
            onBlur=() => 
              setFocus(false);
            
            onFocus=() => 
              setFocus(true);
            
            name=name
          />
        
        name=name
        control=control
        rules=rules
        onChange=([selected]) =>  ( value: selected )

      />
    </div>
  );

export default DatePickerAntd;

我的容器父级使用 react-hooks-form

  const  handleSubmit, control, errors, reset, getValues  = useForm(
    mode: 'onChange',
    validationSchema: schema,
  );

            <DatePickerAntd
              name="deadline"
              title=messages.deadline
              error=errors.deadline
              control=control
              required=isFieldRequired(schema, 'deadline')
            />

这样,它对我有用 ;-)

【讨论】:

【参考方案2】:

我已经构建了一个包装组件,以便更轻松地使用外部受控组件: https://github.com/react-hook-form/react-hook-form-input

import React from 'react';
import useForm from 'react-hook-form';
import  RHFInput  from 'react-hook-form-input';
import Select from 'react-select';

const options = [
   value: 'chocolate', label: 'Chocolate' ,
   value: 'strawberry', label: 'Strawberry' ,
   value: 'vanilla', label: 'Vanilla' ,
];

function App() 
  const  handleSubmit, register, setValue, reset  = useForm();

  return (
    <form onSubmit=handleSubmit(data => console.log(data))>
      <RHFInput
        as=<Select options=options />
        rules= required: true 
        name="reactSelect"
        register=register
        setValue=setValue
      />
      <button
        type="button"
        onClick=() => 
          reset(
            reactSelect: '',
          );
        
      >
        Reset Form
      </button>
      <button>submit</button>
    </form>
  );

试试这个,让我知道它是否让 AntD 的生活更轻松。

【讨论】:

【参考方案3】:

试试这个:

        <DatePicker 
          selected= dueDate  
          // ref=register
          InputField name=`$fieldName.dueDate` 
          onChange=()=>handleChange(index)
          //onChange= handleChange 
           >
          <input 
          type="date" 
          name=`$fieldName.dueDate` 
          inputRef=register
        />

看起来如果您使用的是onChange=handleChange(index),它不会传递函数,而是传递该函数的执行结果。

如果您尝试在handleChange 中访问event,则应从绑定范围手动传递if,否则将为undefined

onChange=()=&gt;handleChange(index, event)

【讨论】:

谢谢@Jarvan - 我试过了。我仍然收到同样的错误:TypeError: Cannot read property 'value' of undefined 这很奇怪。你什么时候得到错误?在页面加载时或更改日期或提交时? handleChange 步骤有问题

以上是关于在 react-hook-form 中设置 DatePicker 的值(来自 antd)的主要内容,如果未能解决你的问题,请参考以下文章

在 WPF/xaml 中设置静态日期时间

在 WPF/xaml 中设置静态日期时间

如何检查是不是从脚本中设置了 python 调试选项

IAR 设置问题

如何将varbinary dat插入sqlserverce

在xib中设置accessibilityIdentifier nil时,必须从用户定义的运行时属性中设置