我有一个表单,它是一组选项卡面板的一部分。表单本身看起来是这样的:
import * as React from "react";
import { useForm, SubmitHandler, Controller } from "react-hook-form";
import { Char } from "../../models";
import { strikerTheme } from "../../../shared/components/StrikerTheme";
import ThemeProvider from "@mui/material/styles/ThemeProvider";
import TextField from "@mui/material/TextField";
import MenuItem from "@mui/material/MenuItem";
import InputAdornment from "@mui/material/InputAdornment";
import { useAppSelector } from "../../../../app/hooks";
import { getTraits, getIdeals } from "../../../shared/specSlice";
import { Quality } from "../../models/specs";
import { CheckboxGroup } from ".";
export const DescriptionForm = ({
onSubmit,
data
}: {
data: Partial<Char>;
onSubmit: SubmitHandler<Partial<Char>>;
}) => {
const specState = useAppSelector(state => state.specState);
console.log('imitial data')
console.log(data)
const { handleSubmit, control } = useForm({defaultValues: data});
const alignments = ['Lawful Good', 'Neutral Good', 'Chaotic Good', 'Lawful Neutral', 'Neutral', 'Chaotic Neutral', 'Lawful Evil', 'Neutral Evil', 'Chaotic Evil']
const traits: Quality[] = getTraits(specState.specKeys);
const ideals: Quality[] = getIdeals(specState.specKeys);
return data && (
<ThemeProvider theme={strikerTheme}>
<form className='form' onSubmit={handleSubmit(onSubmit)}>
<h4>Description</h4>
<div className='form-row'>
<Controller name="name" control={control} render={({ field }) => <TextField sx={{ width: '40ch' }} {...field} label="character name" />} />
</div>
<div className='form-row'>
<Controller name="experience" control={control} render={({ field }) => <TextField {...field} label="experience" />} />
<Controller name="levels" control={control} render={({ field }) => <TextField {...field} label="level" />} />
</div>
<div className='form-row'>
<Controller name="age" control={control} render={({ field }) => <TextField {...field} label="age" />} />
<Controller name="gender" control={control} render={({ field }) => <TextField {...field} label="gender" />} />
<Controller name="height" control={control} render={({ field }) => <TextField {...field} label="height" />} />
<Controller name="weight" control={control} render={({ field }) =>
<TextField {...field} label="weight" InputProps={{
endAdornment: <InputAdornment position="end">kg</InputAdornment>,
}}
/>}
/>
</div>
<div className='form-row'>
<Controller
name="alignment"
control={control}
render={({ field }) => <TextField {...field} label="alignment" helperText="Please select your alignment" select>
{alignments.map((option) => (
<MenuItem key={option} value={option}>
{option}
</MenuItem>
))}
</TextField>}
/>
<div className='form-row'>
<Controller name="traits" control={control} render={({ field }) => <CheckboxGroup
control={control}
label="traits"
options={traits}
{...field}
/>
} />
</div>
<div className='form-row'>
<Controller name="ideals" control={control} render={({ field }) => <CheckboxGroup
control={control}
label="ideals"
options={ideals}
{...field}
/>
} />
</div>
</div>
<button
type='submit'
className='btn btn-block btn-danger'
>
Submit
</button>
</form>
</ThemeProvider>
)
};
请注意,console.log语句显示数据已完全填充,例如:
然而表单呈现为该数据为空(即未定义但具有初始化的默认值)。
这个
onSubmit
实际上在父组件中,并且非常简单:
const onSubmit = async (
data: Partial<Char>
) => {
if (charstate.char) {
await dispatch(editChar(data));
} else {
// its a new char, so create
await dispatch(createChar(data));
}
};
它是有效的,换句话说,我可以填写表单,表单被提交并保存到数据存储中。
我尝试了多种方法,要么让表单等待值被填充,要么尝试强制控件读取值(取决于这是异步问题还是引用问题)。感觉我错过了一些简单的东西。
我错过了什么?