在 Formik 中设置单选按钮组的初始值

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

我正在使用最新版本的 React 表单库,称为 Formik (2.1.5)。

这非常好,但我在初始加载时遇到了单选按钮组的问题。

当我第一次加载表单时,我设置了一堆初始值。

当我执行 console.log 并且所有数据都在那里时,我可以看到它们。

我的输入字段和文本字段完美地加载初始值。

但是我的单选按钮组没有显示应选择哪个单选按钮。

这是我的单选按钮组代码:

<label htmlFor="radioGroup" style={{ display: "block" }}>
    Character Race
</label>
<label>
    <Field type="radio" name="charRace" value="1" />
    Human
</label>
<label>
    <Field type="radio" name="charRace" value="2" />
    Elf
</label>
<label>
    <Field type="radio" name="charRace" value="3" />
    Dwarf
</label>

当表单加载时,以下是初始值:

<Formik
    initialValues={{
        charId: id,
        charName: name,
        charClass: class,
        charRace: race
        charAge: age,
        charRegion: region
    }}
    

现在,当表单加载时,charId、charName、charClass、charAge 和 charRegion 字段均已正确填写。

当我对这些值执行 console.log 时,我会看到它们全部......例如:

charId: 3728,
charName:  Jeriod,
charClass: Wizard,
charRace: 1,
charAge:  34,
charRegion: North

但我不知道如何让 charRace 单选按钮组检查正确的单选按钮。它们总是不受检查。

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

reactjs formik
3个回答
4
投票

charRace
初始值必须是字符串。你可以在这里测试

https://codesandbox.io/s/trusting-hofstadter-hihhj

<Formik
    initialValues={{
        charId: id,
        charName: name,
        charClass: class,
        charRace: String(race),
        charAge: age,
        charRegion: region
    }}
    

4
投票

不确定这是否是正确的策略..

我向我想要预选的单选按钮添加了“checked”属性。仅在 Formik 内的 initialValues 中提及对我来说不起作用。


0
投票

这就是我处理这个问题的方法

  1. 在您的主要组件(Formik Form 或 Wrapper)中,管理初始值的状态

  2. 获取数据后,使用新获取的数据更新初始状态。当然要确保初始/获取数据之间的数据结构相同

  3. 设置初始(状态值)

  4. 为您的 Radio、RadioGroup 创建一个 Wrapper 组件 - 这有利于可重用性

  5. 在这个新的组件包装器中导入 useFormikContext 钩子并利用值和 setFieldValue

  6. 然后您可以按下面的代码所示设置选中的属性,然后在主formik表单中使用此组件

  7. 在formik中使用可重复使用的RadioWrapper,如下所示

     function RadioWrapper({ name, label, legend, grid, options, ...rest }) {
          const { setFieldValue, values } = useFormikContext<any>(); //add correct type for your data
          const [field, meta] = useField(name);
    
          const handlgeChane = (evt: ChangeEvent<HTMLInputElement>) => {
              const { value } = evt.target;
              setFieldValue(name, value);
          };
        const configRadio = {
       ...field,
       ...rest,
     };
    
     // optional settings/configurations
     const configFormControl = { error: false };
    
     if (meta && meta.touched && meta.error) {
      configFormControl.error = true;
     }
    const colRadioGrpStyle = {
     display: "grid",
     gridTemplateColumns: "repeat(3, 1fr)",
     padding: "1rem",
     rowGap: "1rem",
    };
    
    return (
      <FormControl style={{ display: "Grid" }}>
        <FormLabel>{legend}</FormLabel>
        <RadioGroup onChange={handlgeChane}>
          <div style={grid === "col" ? null : colRadioGrpStyle}>
            {options.map((option) => {
              return (
                <FormControlLabel
                  {...configRadio}
                  key={option.key}
                  value={option.value}
                  control={<Radio />}
                  label={option.key}
                  checked={
                    option.value === values[name].value ||
                    field.value === option.value
                  }
                />
              );
            })}
          </div>
         // create configObj or pass in props as needed
            </RadioGroup {...configObj}> 
            <ErrorMessage name={name} component={ErrorText} />
          </FormControl>
        );
      }
    
     export default RadioWrapper;
    
     <Formik
        initialValues={initialValues}
        onSubmit={onSend}
        validationSchema={validationSchema}
        enableReinitialize={true}
     >
        {({ setFieldValue, values }) => (
          <Form className="......">
             <RadioWrapper
          </Form>
        )}
     </Formik>
    
© www.soinside.com 2019 - 2024. All rights reserved.