Javascript 物料界面无法导入并使用ClickAwayListener
我正在为我的项目使用material ui并执行密码更改功能,这是我导入子组件的根文件: Personalize.jsJavascript 物料界面无法导入并使用ClickAwayListener,javascript,reactjs,material-ui,frontend,onclicklistener,Javascript,Reactjs,Material Ui,Frontend,Onclicklistener,我正在为我的项目使用material ui并执行密码更改功能,这是我导入子组件的根文件: Personalize.js import React, { useContext, useState } from 'react'; import Cookies from 'universal-cookie'; import { makeStyles } from '@material-ui/core/styles'; import { withRouter } from 'react-router-d
import React, { useContext, useState } from 'react';
import Cookies from 'universal-cookie';
import { makeStyles } from '@material-ui/core/styles';
import { withRouter } from 'react-router-dom';
import { Grid } from '@material-ui/core';
import { CurrentUserContext } from '../providers/CurrentUserContextProvider';
import Header from '../component/Header';
import Sidebar from '../component/Sidebar';
import ChangeProfileImage from '../component/Main/PersonalizeMain/ChangeProfileImage';
import ChangePassword from '../component/Main/PersonalizeMain/ChangePassword';
const useStyles = makeStyles((theme) => ({
root: {
display: 'flex',
},
toolbar: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
padding: theme.spacing(0, 1),
marginTop: '65px',
// necessary for content to be below app bar
...theme.mixins.toolbar,
},
content: {
flexGrow: 1,
padding: theme.spacing(3),
},
}));
const Personalize = ({ history, location, match }) => {
const classes = useStyles();
const cookies = new Cookies();
const token = cookies.get('token');
if (token === undefined) {
history.push('/login');
}
const { currentUser } = useContext(CurrentUserContext);
const { profileImage } = currentUser;
const [open, setOpen] = useState(false);
const handleDrawerOpen = () => {
setOpen(true);
};
const handleDrawerClose = () => {
setOpen(false);
};
return (
<div className={classes.root}>
<Header open={open} handleDrawerOpen={handleDrawerOpen} />
<Sidebar open={open} handleDrawerClose={handleDrawerClose} />
<main className={classes.content}>
<div className={classes.toolbar}>
<Grid container justify="space-evenly" alignItems="center">
<Grid item>
<ChangeProfileImage profileImage={profileImage} />
</Grid>
<Grid item>
<ChangePassword />
</Grid>
</Grid>
</div>
</main>
</div>
);
};
export default withRouter(Personalize);
import React, { useState } from 'react';
import Cookies from 'universal-cookie';
import { withRouter } from 'react-router-dom';
import { IconButton, TextField, Grid, Snackbar, ClickAwayListener } from '@material-ui/core';
import MuiAlert from '@material-ui/lab/Alert';
import VisibilityIcon from '@material-ui/icons/Visibility';
import VisibilityOffIcon from '@material-ui/icons/VisibilityOff';
import { makeStyles } from '@material-ui/core';
const Alert = (props) => {
return <MuiAlert elevation={6} variant="filled" {...props} />;
};
const useStyles = makeStyles((theme) => ({
MuiInputBaseInput: {
'& .MuiInputBase-input': {
minWidth: '300px',
},
},
customePositionIconButton: { position: 'relative', top: '-50px', right: '-130px' },
}));
const ChangePassword = ({ history, location, match }) => {
const classes = useStyles();
const [passwordVisible, setPasswordVisible] = useState(false);
const [confirmPasswordVisible, setConfirmPasswordVisible] = useState(false);
const [error, setError] = useState('');
const [open, setOpen] = useState(false);
const [password, setPassword] = useState({
newPass: '',
confirmPass: '',
});
const cookies = new Cookies();
const token = cookies.get('token');
const handleSubmit = (event) => {
var charCode = typeof event.which == 'number' ? event.which : event.keyCode;
var { newPass, confirmPass } = password;
if (charCode === 13) {
if (confirmPass === '' || password === '') {
return setError('Emptied Password');
}
if (newPass.trim() === confirmPass.trim()) {
fetch('http://localhost:5000/users/me', {
method: 'PATCH',
headers: {
Authorization: 'Bearer '.concat(token),
'content-type': 'application/json; charset=UTF-8',
},
body: JSON.stringify({ newPass }),
})
.then((response) => {
return response.json();
})
.then((json) => {
var { doc } = json;
if (doc) {
setOpen(true);
}
})
.catch((error) => {
console.error(error);
});
} else {
setError('Passwords Not Matched');
}
}
};
const handleClose = (event, reason) => {
if (reason === 'clickaway') {
return;
}
setOpen(false);
};
const handleClickAway = () => {
setError('');
};
return (
<ClickAwayListener onClickAway={handleClickAway}>
<form noValidate autoComplete="off">
<Grid container direction="column" justify="center" alignItems="center">
<Grid item className={classes.MuiInputBaseInput}>
<TextField
type={passwordVisible ? 'text' : 'password'}
variant="outlined"
label="New Password"
required
onChange={(event) => {
setError('');
setPassword({ ...password, newPass: event.target.value });
}}
onKeyDown={handleSubmit}
error={error === '' ? false : true}
helperText={error}
/>
</Grid>
<Grid item>
<IconButton
className={classes.customePositionIconButton}
onClick={() => {
setPasswordVisible(!passwordVisible);
}}
>
{passwordVisible ? <VisibilityOffIcon /> : <VisibilityIcon />}
</IconButton>
</Grid>
<Grid item className={classes.MuiInputBaseInput}>
<TextField
type={confirmPasswordVisible ? 'text' : 'password'}
variant="outlined"
label="Confirm Password"
required
onChange={(event) => {
setError('');
setPassword({ ...password, confirmPass: event.target.value });
}}
onKeyDown={handleSubmit}
error={error === '' ? false : true}
helperText={error}
/>
</Grid>
<Grid item>
<IconButton
className={classes.customePositionIconButton}
onClick={() => {
setConfirmPasswordVisible(!confirmPasswordVisible);
}}
>
{confirmPasswordVisible ? <VisibilityOffIcon /> : <VisibilityIcon />}
</IconButton>
</Grid>
</Grid>
</form>
<Snackbar open={open} autoHideDuration={6000} onClose={handleClose}>
<Alert onClose={handleClose} severity="success">
Password successfully changed
</Alert>
</Snackbar>
</ClickAwayListener>
);
};
export default withRouter(ChangePassword);
我已将ClickAwayListener
导入到setError
的空字符串中,但我收到了此错误,我无法理解原因。我已经仔细检查过了,没有发现原因
元素类型无效:应为字符串(对于内置组件)
或类/函数,但得到:未定义。您可能忘了导出您的
组件,或者您可能混淆了默认值和
命名导入
只接受一个子组件,不接受组件数组。所以在你的代码中,改变这个
{...}
对此
{...}
它将再次发挥作用