我在ReactJS中实现登录验证时遇到问题。我正在使用Material-UI,Formik和Yap。我已经实现了,但是它有一个错误,提示无效的钩子调用。挂钩只能在功能组件的主体内部调用。
请在下面检查我的代码:
"(a, b, c) => {",
" .....
"}"
答案 0 :(得分:0)
创建一个高阶React组件类,该类将prop和表单处理程序(“ FormikBag”)传递到从提供的选项派生的组件中。
只需导出Form
而不是LoginForm
。还可以使用classes
在组件内部进行const classes = useStyles();
而不是将其作为道具传递。
Working copy of your code is here
代码段
const useStyles = makeStyles(theme => ({
root: {},
cardHeader: {
// backgroundColor: theme.palette.primary.main,
backgroundColor: "blue",
color: "white",
display: "flex",
justifyContent: "center",
fontSize: "2rem",
padding: "15px"
},
textFieldSection: {
padding: "40px 40px 0 40px"
},
loginButtonSection: {
padding: "18px 40px 40px 40px"
},
loginButton: {
width: "100%",
height: "50px",
textTransform: "none",
fontSize: "18px"
}
}));
const LoginForm = props => {
const { className, ...rest } = props;
const classes = useStyles();
const isLoggedIn = true;
const referer = props.referer;
const signIn = () => {
console.log("signin");
};
const {
// classes,
values,
touched,
errors,
isSubmitting,
handleChange,
handleBlur,
handleSubmit
} = props;
if (isLoggedIn) {
// return <Redirect to={referer} />;
console.log("isLoggedIn", isLoggedIn);
}
return (
<Card {...rest} className={clsx(classes.root, className)}>
<form onSubmit={handleSubmit}>
<CardHeader
title="LOGIN"
classes={{
title: classes.cardHeader
}}
className={classes.cardHeader}
/>
<CardContent className={classes.textFieldSection}>
<TextField
fullWidth
label="Username"
name="username"
type="text"
variant="outlined"
value={values.username}
onChange={handleChange}
onBlur={handleBlur}
helperText={touched.username ? errors.username : ""}
error={touched.username && Boolean(errors.username)}
InputProps={{
endAdornment: (
<InputAdornment>
<AccountCircle />
</InputAdornment>
)
}}
/>
<TextField
fullWidth
label="Password"
name="password"
style={{ marginTop: "1rem" }}
type="password"
variant="outlined"
value={values.password}
onChange={handleChange}
onBlur={handleBlur}
helperText={touched.password ? errors.password : ""}
error={touched.password && Boolean(errors.password)}
InputProps={{
endAdornment: (
<InputAdornment>
<LockIcon />
</InputAdornment>
)
}}
/>
</CardContent>
<CardActions className={classes.loginButtonSection}>
<Button
type="submit" //<----------- see here
color="primary"
variant="contained"
onClick={signIn}
className={classes.loginButton}
disabled={isSubmitting}
>
Log In
</Button>
</CardActions>
</form>
</Card>
);
};
let yup = require("yup");
const Form = withFormik({
mapPropsToValues: ({ username, password }) => {
return {
username: username || "",
password: password || ""
};
},
validationSchema: yup.object().shape({
username: yup.string().required("Required"),
password: yup
.string()
.min(8, "Password must contain at least 8 characters")
.required("Enter your password")
}),
handleSubmit: (values, { setSubmitting }) => {
setTimeout(() => {
// submit to the server
alert(JSON.stringify(values, null, 2));
setSubmitting(false);
}, 1000);
}
})(LoginForm);
LoginForm.propTypes = {
className: PropTypes.string
};
// export default LoginForm(useStyles)(Form);
export default Form;