使用来自单独组件的值更新 Formik initialValues

updating Formik initialValues with values from separate component

我有一个用 React select 制作的 select 输入组件,我在一个 Formik 表单中。我正在尝试让我的 Formik 值更新为从 React Select 返回的值。完成这项工作的最佳方法是什么?

在我的 Formik 表单中:

  const initialValues = {
    firstName: '',
    lastName: '',
    jobPosition: '',
    email: '',
    phoneNumber: '',
    languages: [],
    files: []
  };

<SelectInput
    name='languages'
    options={languages}
    isMulti={true}
    onChange={handleChange}
    type='select'
/>

我的Select输入组件:

import React from 'react'
import Select from "react-select";
import { inputStyles } from './styles';
import PropTypes from 'prop-types';
import { useField } from 'formik';

const SelectInput = ({ options, placeholder, isMulti, ...props }) => {


  const [field] = useField(props)


  return (
    <div style={{ marginTop: '1.5rem' }}>
      <Select
        {...field}
        styles={inputStyles}
        className="basic-single"
        classNamePrefix="select"
        isClearable={true}
        isSearchable={true}
        placeholder={placeholder}
        options={options}
        isMulti={isMulti}
      />
    </div>
  )
}

在当前状态下,当 select 选择一个选项时,我收到一个类型错误:

Formik.tsx:600 Uncaught TypeError: Cannot read properties of undefined (reading 'type')

我找不到您传递给 SelectInput 的 onChange 属性的 handleChange 函数,所以我无法告诉您代码中的问题是什么,但您可以使用 useFormikContext 挂钩来获取 setFieldValue 方法。您可以将此函数从父组件传递给 SelectInput,但更好的方法是将此函数移至您的 SelectInput 组件。您现在必须从道具中读取字段名称。所以它看起来像这样:

   const { setFieldValue } = useFormikContext();

   const handleChange = (option) => {
       setFieldValue(props.name, option);
   };

将此代码添加到您的 SelectInput 组件中。 另请注意,您可以在此处使用 useFormikContext,因为 SelectInput 在 formik 的表单组件内部使用。如果你想在 SelectInput 组件之外定义 handleChange,你可以给你的表单一个 ref 并在父组件中使用 ref.current.setFieldValue。

如果你需要在 Formik 组件之外使用 handleChange 函数,你可以这样做:

  const ref = useRef();
  
  const handleChange = (option) => {
     ref.current.setFieldValue("languages", option);
  };

  return (
     <Formik
        //other props
        innerRef={ref}
     >
     {/* your inputs */}
     </Formik>
  );