【问题标题】:React (Material UI) - Issues with form in componentReact (Material UI) - 组件中的表单问题
【发布时间】:2020-11-19 21:09:58
【问题描述】:

所以,我正在尝试为网络应用创建一个注册表单 - 但遇到了一些问题。 我正在使用带有函数的钩子来呈现注册页面,我从登录页面路由到该页面。

假设我直接从函数(注册)的返回中返回 html,它可以正常工作,但是一旦注册完成,我希望交换表单以确认它正在发送。

据我所知,人们只需将每个 html 包装在箭头函数中,然后在使用 bool 或类似函数之间切换。但这就是问题所在。

TLDR;

其中一个注册文本字段自动完成,从 API 获取。然后 API 将内容保存在挂钩变量(地址)中。第二次我更新地址变量,表单似乎重置了 - 光标转到第一个输入字段。

这仅在我将 html 包装在组件中时发生,而不是在我将所有 html 插入(注册)返回时发生。

我试着清理了一下,但代码或多或少看起来像这样。 任何帮助或指示都会很棒:)

export default function SignUp(props)
{

    const [activeStep, setActiveStep] = React.useState(0);
    const [addresses, setAddresses] = React.useState([{ tekst: '' }]);

    const APICall = async (e) =>
    {
        e.preventDefault();

        // Fetchs JSON and set Addresses hook

    }

    const handleSubmit = props => form =>
    {
        form.preventDefault()
        setActiveStep(activeStep + 1);
    }

    const CreateAccount = (e) =>
    {
        return (
            <Container component="main" maxWidth="xs">
                <CssBaseline />
                <div className={classes.paper}>
                    <Avatar className={classes.avatar}>
                        <LockOutlinedIcon />
                    </Avatar>
                    <Typography component="h1" variant="h5">
                        Opret konto
        </Typography>
                    <form className={classes.form} noValidate
                        onSubmit={handleSubmit(props)}>
                        <Autocomplete
                            id="address"
                            options={addresses}
                            getOptionLabel={(option) => option.tekst}
                            style={{ width: 300 }}
                            renderInput={(params) =>
                                <TextField {...params} label="Combo box" variant="outlined" onChange={userTest} />
                            }
                        />
                        <Button
                            type="submit"
                            fullWidth
                            variant="contained"
                            color="primary"
                            className={classes.submit}
                        >
                            Sign Up
                        </Button>

                    </form>
                </div>
                <Box mt={5}>
                    <Copyright />
                </Box>
            </Container>
        );
    }

    const CreateAccountACK = () =>
    {
        return (
            <React.Fragment>
                <Container component="main" maxWidth="xs">
                    <CssBaseline />
                    <div className={classes.paper}>
                        <Avatar className={classes.avatar}>
                            <LockOutlinedIcon />
                        </Avatar>
                        <Typography component="h1" variant="h5">
                            Nyt konto oprettet!
            </Typography>
                        <Button
                            type="button"
                            variant="contained"
                            color="primary"
                            className={classes.submit}
                            onClick={() => { props.history.push('/') }}
                        >
                            Ok
            </Button>

                    </div>
                    <Box mt={8}>
                        <Copyright />
                    </Box>
                </Container>
            </React.Fragment>
        );
    }

    return (
        <div>
            {activeStep == 0 ? <CreateAccount /> : <CreateAccountACK />}
        </div>
    )
}

【问题讨论】:

  • 嗨,1. 您是否错过了在代码 sn-p 中包含 address 挂钩? 2.这里随机猜测??? - 当我们将元素包装在组件中并且 React 有条件地渲染它时,它每次重新渲染时都会渲染一个新实例,因此如果变量没有永久存储在状态/变量中,它将重置。但是,想详细了解是什么问题
  • 嗨 Rejo,感谢您的评论 :)。我写错了,这个钩子叫做addresses [addresses, setAddresses]。有没有更好的选择来代替我做事的方式?非常新的反应:)
  • Hi Ills,我可以看到您正在设计一个分步表单(类似向导),我建议您查看 stepper material-ui.com/components/steppers,它允许您拥有不同的页面和该过程的步骤。欢迎来到 React,令人敬畏的另一面! :)
  • 一旦对组件进行了选择,您可以将它们存储在其状态挂钩中,以使其在整个过程中保持不变。即,拥有其状态众所周知且可互操作的受控组件是件好事。参考reactjs.org/docs/forms.html#controlled-components
  • 通过将函数分离成它们自己的函数组件,包括每个需要的变量/钩子/函数来让它工作。似乎工作,虽然我没有找到一个非常优雅的解决方案:D 用代码更新了帖子。

标签: javascript html reactjs components material-ui


【解决方案1】:

通过将每个函数分解为自己的函数组件,然后使用条件从主类(注册)呈现它们来使其工作。页面之间的交换通过回调到此函数中的“handlesubmit”来处理。在最后一页路由回主页面时传递历史记录。感觉这不是执行此操作的最佳方式 =D,但它避免了键入时重新渲染的问题。

所以现在注册只是返回...

export default function SignUp(props)
{
  const [activeStep, setActiveStep] = React.useState(0);

  const handleSubmit = props => form =>
  {
    form.preventDefault()
    console.log(form)
    setActiveStep(activeStep + 1);
  }

  return (
    <div>
      {activeStep == 0 ? <CreateAccount handleSubmit={handleSubmit} /> : <CreateAccountACK handleSubmit={handleSubmit} history={props.history}/>}
    </div>
  )
}

并且每个函数、钩子/变量都存在于它们自己的文件/函数中。

【讨论】:

    猜你喜欢
    • 2018-07-04
    • 2016-09-29
    • 2018-01-13
    • 1970-01-01
    • 2022-01-10
    • 2020-07-26
    • 2020-06-30
    • 2021-01-28
    • 2021-02-11
    相关资源
    最近更新 更多