【问题标题】:Setting the value of DatePicker (from antd) in react-hook-form在 react-hook-form 中设置 DatePicker 的值(来自 antd)
【发布时间】: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);
    }

但每一代都有相同的错误

【问题讨论】:

    标签: javascript reactjs react-hooks antd react-hook-form


    【解决方案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 步骤有问题
        猜你喜欢
        • 2021-03-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-17
        • 2021-01-26
        • 2020-12-26
        • 1970-01-01
        • 2020-08-05
        相关资源
        最近更新 更多