Material-ui 模态 forwardRef 警告
Material-ui modal forwardRef warning
"Here is the form that logs user in used and I used forwardRef here, In SignInModal I wraped this component but it keeps give me warning"
import React, { useState, useEffect } from "react";
import PropTypes from "prop-types";
import Avatar from "@material-ui/core/Avatar";
import Button from "@material-ui/core/Button";
import CssBaseline from "@material-ui/core/CssBaseline";
import FormControl from "@material-ui/core/FormControl";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import Checkbox from "@material-ui/core/Checkbox";
import Input from "@material-ui/core/Input";
import InputLabel from "@material-ui/core/InputLabel";
import LockOutlinedIcon from "@material-ui/icons/LockOutlined";
import Paper from "@material-ui/core/Paper";
import Typography from "@material-ui/core/Typography";
import withStyles from "@material-ui/core/styles/withStyles";
import { connect } from "react-redux";
import { login } from "../actions/auth";
import Grid from "@material-ui/core/Grid";
import Link from "@material-ui/core/Link";
import Alert from "./Alert";
import { Link as RouterLink } from "react-router-dom";
const styles = theme => ({
main: {
width: "auto",
display: "block", // Fix IE 11 issue.
marginLeft: theme.spacing(3),
marginRight: theme.spacing(3),
[theme.breakpoints.up(400 + theme.spacing(3 * 2))]: {
width: 400,
marginLeft: "auto",
marginRight: "auto"
}
},
paper: {
marginTop: theme.spacing(8),
display: "flex",
flexDirection: "column",
alignItems: "center",
padding: `${theme.spacing(2)}px ${theme.spacing(3)}px ${theme.spacing(3)}px`
},
avatar: {
margin: theme.spacing(),
backgroundColor: "black"
},
form: {
width: "100%", // Fix IE 11 issue.
marginTop: theme.spacing()
},
submit: {
marginTop: theme.spacing(3)
}
});
// const SignIn = props => {
const SignIn = React.forwardRef((props, ref) => {
const { classes, isAuthenticated, login, modalControl } = props;
const [formData, setFormData] = useState({
email: "",
password: ""
});
const { email, password } = formData;
const onChange = e =>
setFormData({ ...formData, [e.target.name]: e.target.value });
const onSubmit = async e => {
e.preventDefault();
login(email, password);
};
if (isAuthenticated) {
modalControl();
}
// else if (password != password1) {
// setAlert("password do not match", "danger");
// }
return (
<main ref={ref} className={classes.main}>
<CssBaseline />
<Paper className={classes.paper}>
<Avatar className={classes.avatar}>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign in
</Typography>
<Alert />
<form className={classes.form} onSubmit={e => onSubmit(e)}>
<FormControl margin="normal" fullWidth>
<InputLabel htmlFor="email">Email Address</InputLabel>
<Input
id="email"
name="email"
autoComplete="email"
value={email}
onChange={e => onChange(e)}
autoFocus
/>
</FormControl>
<FormControl margin="normal" fullWidth>
<InputLabel htmlFor="password">Password</InputLabel>
<Input
name="password"
type="password"
id="password"
value={password}
onChange={e => onChange(e)}
autoComplete="current-password"
/>
</FormControl>
<FormControlLabel
control={<Checkbox value="remember" color="primary" />}
label="Remember me"
/>
<Button
type="submit"
fullWidth
variant="contained"
color="default"
className={classes.submit}
>
Sign in
</Button>
<Grid container>
<Grid item xs>
<Link
variant="body2"
component={RouterLink}
to="/PasswordReset"
underline="none"
>
Forgot password?
</Link>
</Grid>
<Grid item>
<Link href="#" variant="body2">
{"Don't have an account? Sign Up"}
</Link>
</Grid>
</Grid>
</form>
</Paper>
</main>
);
});
SignIn.propTypes = {
classes: PropTypes.object.isRequired,
login: PropTypes.func.isRequired,
isAuthenticated: PropTypes.bool,
modalControl: PropTypes.func.isRequired
};
const mapStateToProps = state => ({
isAuthenticated: state.auth.isAuthenticated
});
export default connect(mapStateToProps, { login })(withStyles(styles)(SignIn));
import React, { useState, useRef, useEffect } from "react";
import PropTypes from "prop-types";
import { withStyles } from "@material-ui/core/styles";
import Typography from "@material-ui/core/Typography";
import Modal from "@material-ui/core/Modal";
import Button from "@material-ui/core/Button";
import SignIn from "./SignIn";
function getModalStyle() {
const top = 25;
const left = 25;
return {
top: `${top}%`,
left: `${left}%`,
transform: `translate(-${top}%, -${left}%)`
};
}
const styles = theme => ({
button: {
margin: theme.spacing(1)
}
});
const SigninModal = props => {
const [open, setOpen] = useState(false);
const handleOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
const { classes, SigninModalRef } = props;
return (
<div>
<Button
className={classes.button}
variant="contained"
onClick={handleOpen}
>
Sign In
</Button>
<Modal
aria-labelledby="simple-modal-title"
aria-describedby="simple-modal-description"
open={open}
onClose={handleClose}
>
<SignIn modalControl={handleClose} />
</Modal>
</div>
);
};
SigninModal.propTypes = {
classes: PropTypes.object.isRequired
};
export default withStyles(styles)(SigninModal);
我使用 Signinmodal 来包装 Signin 表单,不确定我是否正确使用了 forwardref,它仍然给我警告“函数组件不能被赋予 refs。尝试访问此 ref 将失败。您是要使用 React.forwardRef() 吗?“
使用 ref 为我解决了这个问题。
你的情况
<SignIn ref={ref} modalControl={handleClose} />
const SigninModal = React.forwardRef( (ref, props) => {
return (
<div ref={ref}>
... rest of the code
})
"Here is the form that logs user in used and I used forwardRef here, In SignInModal I wraped this component but it keeps give me warning"
import React, { useState, useEffect } from "react";
import PropTypes from "prop-types";
import Avatar from "@material-ui/core/Avatar";
import Button from "@material-ui/core/Button";
import CssBaseline from "@material-ui/core/CssBaseline";
import FormControl from "@material-ui/core/FormControl";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import Checkbox from "@material-ui/core/Checkbox";
import Input from "@material-ui/core/Input";
import InputLabel from "@material-ui/core/InputLabel";
import LockOutlinedIcon from "@material-ui/icons/LockOutlined";
import Paper from "@material-ui/core/Paper";
import Typography from "@material-ui/core/Typography";
import withStyles from "@material-ui/core/styles/withStyles";
import { connect } from "react-redux";
import { login } from "../actions/auth";
import Grid from "@material-ui/core/Grid";
import Link from "@material-ui/core/Link";
import Alert from "./Alert";
import { Link as RouterLink } from "react-router-dom";
const styles = theme => ({
main: {
width: "auto",
display: "block", // Fix IE 11 issue.
marginLeft: theme.spacing(3),
marginRight: theme.spacing(3),
[theme.breakpoints.up(400 + theme.spacing(3 * 2))]: {
width: 400,
marginLeft: "auto",
marginRight: "auto"
}
},
paper: {
marginTop: theme.spacing(8),
display: "flex",
flexDirection: "column",
alignItems: "center",
padding: `${theme.spacing(2)}px ${theme.spacing(3)}px ${theme.spacing(3)}px`
},
avatar: {
margin: theme.spacing(),
backgroundColor: "black"
},
form: {
width: "100%", // Fix IE 11 issue.
marginTop: theme.spacing()
},
submit: {
marginTop: theme.spacing(3)
}
});
// const SignIn = props => {
const SignIn = React.forwardRef((props, ref) => {
const { classes, isAuthenticated, login, modalControl } = props;
const [formData, setFormData] = useState({
email: "",
password: ""
});
const { email, password } = formData;
const onChange = e =>
setFormData({ ...formData, [e.target.name]: e.target.value });
const onSubmit = async e => {
e.preventDefault();
login(email, password);
};
if (isAuthenticated) {
modalControl();
}
// else if (password != password1) {
// setAlert("password do not match", "danger");
// }
return (
<main ref={ref} className={classes.main}>
<CssBaseline />
<Paper className={classes.paper}>
<Avatar className={classes.avatar}>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign in
</Typography>
<Alert />
<form className={classes.form} onSubmit={e => onSubmit(e)}>
<FormControl margin="normal" fullWidth>
<InputLabel htmlFor="email">Email Address</InputLabel>
<Input
id="email"
name="email"
autoComplete="email"
value={email}
onChange={e => onChange(e)}
autoFocus
/>
</FormControl>
<FormControl margin="normal" fullWidth>
<InputLabel htmlFor="password">Password</InputLabel>
<Input
name="password"
type="password"
id="password"
value={password}
onChange={e => onChange(e)}
autoComplete="current-password"
/>
</FormControl>
<FormControlLabel
control={<Checkbox value="remember" color="primary" />}
label="Remember me"
/>
<Button
type="submit"
fullWidth
variant="contained"
color="default"
className={classes.submit}
>
Sign in
</Button>
<Grid container>
<Grid item xs>
<Link
variant="body2"
component={RouterLink}
to="/PasswordReset"
underline="none"
>
Forgot password?
</Link>
</Grid>
<Grid item>
<Link href="#" variant="body2">
{"Don't have an account? Sign Up"}
</Link>
</Grid>
</Grid>
</form>
</Paper>
</main>
);
});
SignIn.propTypes = {
classes: PropTypes.object.isRequired,
login: PropTypes.func.isRequired,
isAuthenticated: PropTypes.bool,
modalControl: PropTypes.func.isRequired
};
const mapStateToProps = state => ({
isAuthenticated: state.auth.isAuthenticated
});
export default connect(mapStateToProps, { login })(withStyles(styles)(SignIn));
import React, { useState, useRef, useEffect } from "react";
import PropTypes from "prop-types";
import { withStyles } from "@material-ui/core/styles";
import Typography from "@material-ui/core/Typography";
import Modal from "@material-ui/core/Modal";
import Button from "@material-ui/core/Button";
import SignIn from "./SignIn";
function getModalStyle() {
const top = 25;
const left = 25;
return {
top: `${top}%`,
left: `${left}%`,
transform: `translate(-${top}%, -${left}%)`
};
}
const styles = theme => ({
button: {
margin: theme.spacing(1)
}
});
const SigninModal = props => {
const [open, setOpen] = useState(false);
const handleOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
const { classes, SigninModalRef } = props;
return (
<div>
<Button
className={classes.button}
variant="contained"
onClick={handleOpen}
>
Sign In
</Button>
<Modal
aria-labelledby="simple-modal-title"
aria-describedby="simple-modal-description"
open={open}
onClose={handleClose}
>
<SignIn modalControl={handleClose} />
</Modal>
</div>
);
};
SigninModal.propTypes = {
classes: PropTypes.object.isRequired
};
export default withStyles(styles)(SigninModal);
我使用 Signinmodal 来包装 Signin 表单,不确定我是否正确使用了 forwardref,它仍然给我警告“函数组件不能被赋予 refs。尝试访问此 ref 将失败。您是要使用 React.forwardRef() 吗?“
使用 ref 为我解决了这个问题。 你的情况
<SignIn ref={ref} modalControl={handleClose} />
const SigninModal = React.forwardRef( (ref, props) => {
return (
<div ref={ref}>
... rest of the code
})