使用@unform 和 react-datepicker 破坏编辑屏幕的日期选择器组件

Datepicker component breaking an edit screen, using @unform and react-datepicker

我在 UnForm 中为 select 个日期创建了以下组件:

export default function DatePickerInput({ name, ...rest }) {
  const datepickerRef = useRef(null);
  const { fieldName, defaultValue = '', registerField } = useField(name);

  const [date, setDate] = useState(defaultValue || null);
  useEffect(() => {
    registerField({
      name: fieldName,
      ref: datepickerRef.current,
      path: 'props.selected',
    });
  }, [fieldName, registerField]);

  return (
    <Label htmlFor={fieldName}>
      <UnInput>
        <ReactDatePicker
          ref={datepickerRef}
          selected={date}
          onChange={setDate}
          dateFormat="dd/MM/yyyy"
          placeholderText="dd/mm/aaaa"
          writable="true"
          {...rest}
        />
      </UnInput>
    </Label>
  );
}

为了保存记录,组件正常工作,加载和保存我 select 编辑的日期。当我要编辑记录时,尝试在初始加载中加载日期时,页面损坏并显示以下错误:

Unhandled Rejection (TypeError): Cannot assign to read only property 'selected' of object '#<Object>'

如果我注释掉 path: 'props.selected' 行,在 useEffect () 中屏幕没有损坏,但组件中没有填写日期。它是如何工作的?

问题:

formRef.current.setFieldValue('birthday',value) 这将尝试在提供的 path 上设置值,在我们的例子中提供的路径是 props.selected.

并且 props.selected 是只读的 属性 所以你不能在 props 上设置值因此错误。

useEffect(() => {
    registerField({
      name: fieldName,
      ref: datepickerRef.current,
      path: 'props.selected', // <---- this is props, and it's readonly
      clearValue: (ref) => {
        ref.clear();
      },
    });
}, [fieldName, registerField]);

解法:

您可以删除 path 并使用 gettersetter 方法,命名为 getValuesetValue :

setValue :设置初始值或从 setFieldValue

传递的任何值

getValue : 在提交时获得价值

useEffect(() => {
    registerField({
      name: fieldName,
      ref: datepickerRef.current,
      clearValue: ref => {
        ref.clear();
      },
      setValue: (e, v) => {
        setDate(new Date(v)); // <---- Setting up default value 
      },
      getValue: () => {
        return datepickerRef.current.props.selected; // to get selected value from Date picker's props
        // OR
        return Date.toString(); // to get selected value from state it self
      }
    });
}, [fieldName, registerField]);

工作演示