如何将输入值从子表单组件传递到其父组件的状态,以便使用 react 钩子提交?



我正在设置一个多步骤表单来处理使用Next.js和Material-UI登录。在位于pages/signup.jssignup.js页面中。我的多步骤表单已创建。在此页面中,要显示为步骤内容的子组件在getStepContent(step)中定义,主组件在其下方SignInSide调用。前进和后退的步骤也在signup.js页面上定义。子表单组件仅包含输入。我正在尝试将输入到子组件表单输入中的数据传递到注册页面中的父组件状态,signup.js以便我可以提交它。父组件和子组件都是使用状态反应钩子的功能组件。

我已经尝试将 props 从父组件传递到子组件,然后将 TextField 组件的"值"定义为 {props.value},当我使用控制台测试它时,这很有效.log父组件中的值我看到了字母通过,但是没有名称:附加到它上面,它只是作为字母通过,所以我尝试添加 [name]: event.target.value但是当我尝试在输入字段中写入文本时,它只是说[对象对象]但是,在控制台中我可以看到[对象对象](在此处插入字母(,因此它记录文本但不正确,输入的文本在输入框中不可见。

这是步骤内容所在的地方。

const steps = ['Welcome', 'Information', 'Creative', 'Confirm'];
function getStepContent(step) {
const [value, setValue] = React.useState('');
//set state for returned input values
function handleChange(newValue) {
setValue(newValue);
}
switch (step) {
case 0:
return (
<div style={{ padding: '8em 0 4em' }}>
<Hero title='Welcome' paragraph="Let's get you signed up." />
</div>
);
case 1:  // Form Components
return <CredentialsForm value={value} onChange={handleChange} />;
case 2:
return <CreativeForm />;
case 3:
return <Review />;
default:
throw new Error('Unknown step');
}
}
// Sign In Page
export default function SignInSide() {
const classes = useStyles();
const [activeStep, setActiveStep] = React.useState(0);
const [form, setForm] = React.useState(false);
// Forward and Back button functions, the buttons are defined here, in the parent page component.
const handleNext = () => {
setActiveStep(activeStep + 1);
};
const handleBack = () => {
setActiveStep(activeStep - 1);
};
const handleFormExtend = () => {
setForm(true);
setActiveStep(activeStep + 1);
};
return (
...
)
}

父组件是SignInSide。我使用材料用户界面。在这里可以看到 im 使用的步进器表单的示例:https://material-ui.com/getting-started/templates/checkout/其类似的代码中,我只是将文本字段更改为大纲,并为从父级传递的 props 设置逻辑。

组件内部<CredentialsForm value={value} onChange={handleChange} />

export default function CredentialsForm(props) {
const classes = useStyles();
// Floating Form Label
const inputLabel = React.useRef(null);
const [labelWidth, setLabelWidth] = React.useState(0);
React.useEffect(() => {
setLabelWidth(inputLabel.current.offsetWidth);
}, []);
//Send input value to parent state
const handleChange = name => event => {
props.onChange({
[name]: event.target.value
});
};
return (
<div className={classes.paper}>
<Avatar className={classes.avatar}>
<LockOutlinedIcon />
</Avatar>
<Typography component='h1' variant='h5'>
Who Are U?
</Typography>
<form className={classes.form} noValidate>
<Grid container spacing={2}>
<Grid item xs={2} md={2}>
<FormControl
margin='normal'
variant='outlined'
fullWidth
required
className={classes.formControl}
>
<InputLabel
ref={inputLabel}
htmlFor='outlined-userTitle-native-simple'
>
Title
</InputLabel>
<Select
native
value={props.value}
onChange={handleChange('title')}
labelWidth={labelWidth}
required
inputProps={{
name: 'title'
}}
>
<option value='' />
<option value={10}>Mr.</option>
<option value={20}>Ms.</option>
<option value={20}>Mrs.</option>
<option value={30}>Non-Binary</option>
</Select>
</FormControl>
</Grid>
<Grid item xs={5} md={5}>
<TextField
variant='outlined'
margin='normal'
required
fullWidth
value={props.value}
onChange={handleChange('firstName')}
id='first'
label='First Name'
name='firstname'
/>
</Grid>
</Grid>
</form>
</div>
);
}

预期:在用户输入时,子组件将输入保存为状态,并将其传递给父组件,以便它可以提交数据进行注册。

实际:输入成功传递给父级,但格式错误。它作为"[对象对象](用户在此处键入的字母("传递,在输入字段中,用户只能看到控制台中看到的[对象对象]。没有错误。

你的问题在这里:

const handleChange = name => event => {
props.onChange({
[name]: event.target.value
});
};

您正在为props.onChange函数提供一个对象,但该函数正在更新使用字符串值初始化的状态挂钩。然后,将文本值设置为对象,而它曾经是一个字符串,为您提供外观奇怪的对象文本。

此外,您将所有表单值设置为父状态中的相同字符串。

若要解决此问题,请将状态设置为对象而不是字符串。

在父级中:

const [values, setValues] = React.useState({title: '', firstName: ''});
....
function handleChange(newValue) {
setValues({...values, ...newValue});
}
....
return <CredentialsForm values={values} onChange={handleChange} />;

在儿童中:

<Select
native
value={props.values.title} // Change to this
onChange={handleChange('title')}
labelWidth={labelWidth}
required
inputProps={{
name: 'title'
}}
>
....
<TextField
variant='outlined'
margin='normal'
required
fullWidth
value={props.values.firstName} // Change to this
onChange={handleChange('firstName')}
id='first'
label='First Name'
name='firstname'
/>

推荐但不是必需的:我会去掉表单组件中的handleChange函数,因为它并没有真正增加价值。然后直接从输入调用props.onChange,并将父handleChange更改为:

const handleChange = name => event => {
setValues({...values, [name]: event.target.value});
}

相关内容

  • 没有找到相关文章

最新更新