Javascript useEffect()的重定向不起作用?
如果登录成功并且令牌存储在localStorage中,则应将我重定向到专用路由,即/panel。如果不是,我应该显示来自淋浴ROR()的错误消息 目前,如果登录不成功,将显示我的错误消息,因此一切正常。但是,如果存在令牌,则仍然没有重定向Javascript useEffect()的重定向不起作用?,javascript,reactjs,typescript,react-router,react-hooks,Javascript,Reactjs,Typescript,React Router,React Hooks,如果登录成功并且令牌存储在localStorage中,则应将我重定向到专用路由,即/panel。如果不是,我应该显示来自淋浴ROR()的错误消息 目前,如果登录不成功,将显示我的错误消息,因此一切正常。但是,如果存在令牌,则仍然没有重定向 function LoginPage (){ const [state, setState] = useState({ email: '', password: '', }); const [submitted, setSubmi
function LoginPage (){
const [state, setState] = useState({
email: '',
password: '',
});
const [submitted, setSubmitted] = useState(false);
const [shouldRedirect, setShouldRedirect] = useState(false);
function ShowError(){
if (!localStorage.getItem('token'))
{
console.log('Login Not Successful');
return (
<ThemeProvider theme={colortheme}>
<Typography color='primary'>
Login Unsuccessful
</Typography>
</ThemeProvider>)
}
}
// function FormSubmitted(){
// setSubmitted(true);
// console.log('Form submitted');
// }
// function RedirectionToPanel(){
// console.log('check');
// if(submitted && localStorage.getItem('token')){
// console.log('Finall');
// return <Redirect to='/panel'/>
// }
// }
useEffect(() => {
if(localStorage.getItem('token')){
setShouldRedirect(true);
}
},[] );
function submitForm(LoginMutation: any) {
setSubmitted(true);
const { email, password } = state;
if(email && password){
LoginMutation({
variables: {
email: email,
password: password,
},
}).then(({ data }: any) => {
localStorage.setItem('token', data.loginEmail.accessToken);
})
.catch(console.log)
}
}
return (
<Mutation mutation={LoginMutation}>
{(LoginMutation: any) => (
<Container component="main" maxWidth="xs">
<CssBaseline />
<div style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center'
}}>
<Avatar>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign in
</Typography>
<Formik
initialValues={{ email: '', password: '' }}
onSubmit={(values, actions) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
actions.setSubmitting(false);
}, 1000);
}}
validationSchema={schema}
>
{props => {
const {
values: { email, password },
errors,
touched,
handleChange,
isValid,
setFieldTouched
} = props;
const change = (name: string, e: any) => {
e.persist();
handleChange(e);
setFieldTouched(name, true, false);
setState( prevState => ({ ...prevState, [name]: e.target.value }));
};
return (
<form style={{ width: '100%' }}
onSubmit={e => {e.preventDefault();
submitForm(LoginMutation);}}>
<TextField
variant="outlined"
margin="normal"
id="email"
fullWidth
name="email"
helperText={touched.email ? errors.email : ""}
error={touched.email && Boolean(errors.email)}
label="Email"
value={email}
onChange={change.bind(null, "email")}
/>
<TextField
variant="outlined"
margin="normal"
fullWidth
id="password"
name="password"
helperText={touched.password ? errors.password : ""}
error={touched.password && Boolean(errors.password)}
label="Password"
type="password"
value={password}
onChange={change.bind(null, "password")}
/>
{submitted && ShowError()}
<FormControlLabel
control={<Checkbox value="remember" color="primary" />}
label="Remember me"
/>
<br />
<Button className='button-center'
type="submit"
disabled={!isValid || !email || !password}
// onClick={handleOpen}
style={{
background: '#6c74cc',
borderRadius: 3,
border: 0,
color: 'white',
height: 48,
padding: '0 30px'
}}
>
Submit</Button>
<br></br>
<Grid container>
<Grid item xs>
<Link href="#" variant="body2">
Forgot password?
</Link>
</Grid>
<Grid item>
<Link href="#" variant="body2">
{"Don't have an account? Sign Up"}
</Link>
</Grid>
</Grid>
</form>
)
}}
</Formik>
</div>
<Box mt={8}>
<Copyright />
</Box>
{/* {submitted && <Redirect to='/panel'/>} */}
</Container>
)
}
</Mutation>
);
}
export default LoginPage;
函数登录页(){
常量[状态,设置状态]=使用状态({
电子邮件:“”,
密码:“”,
});
const[submited,setSubmitted]=使用状态(false);
const[shouldRedirect,setShouldRedirect]=useState(false);
函数名为ror(){
如果(!localStorage.getItem('token'))
{
log('Login Not Successful');
返回(
登录失败
)
}
}
//函数FormSubmitted(){
//setSubmitted(true);
//console.log(“提交的表单”);
// }
//函数重定向topanel(){
//console.log('check');
//if(已提交&&localStorage.getItem('token')){
//console.log('Finall');
//返回
// }
// }
useffect(()=>{
if(localStorage.getItem('token')){
setShouldRedirect(true);
}
},[] );
函数提交形式(LoginMutation:any){
setSubmitted(true);
const{email,password}=state;
如果(电子邮件和密码){
逻辑置换({
变量:{
电邮:电邮,,
密码:密码,
},
})。然后({data}:any)=>{
localStorage.setItem('token',data.loginEmail.accessToken);
})
.catch(console.log)
}
}
返回(
{(LoginMutation:any)=>(
登录
{
设置超时(()=>{
警报(JSON.stringify(值,null,2));
动作。设置提交(错误);
}, 1000);
}}
validationSchema={schema}
>
{props=>{
常数{
值:{email,password},
错误,
感动的,
handleChange,
是有效的,
Setfieldtouch
}=道具;
常量更改=(名称:字符串,e:any)=>{
e、 坚持();
handleChange(e);
setFieldTouched(名称、真、假);
setState(prevState=>({…prevState,[名称]:e.target.value}));
};
返回(
{e.preventDefault();
submitForm(LoginMutation);}>
{已提交(&R)}
提交
忘记密码了?
{“没有帐户?注册”}
)
}}
{/*{已提交&}*/}
)
}
);
}
导出默认登录页面;
我的App.tsx:
const token = localStorage.getItem('token');
const PrivateRoute = ({component, isAuthenticated, ...rest}: any) => {
const routeComponent = (props: any) => (
isAuthenticated
? React.createElement(component, props)
: <Redirect to={{pathname: '/404'}}/>
);
return <Route {...rest} render={routeComponent}/>;
};
export default function App() {
return (
<div>
<BrowserRouter>
<Switch>
<Route exact path='/' component= {HomePage}></Route>
<Route path='/login' component= {LoginPage}></Route>
<Route path='/404' component= {Error404Page}></Route>
<PrivateRoute
path='/panel'
isAuthenticated={token}
component={PanelHomePage}
/>
<Redirect from='*' to='/404' />
</Switch>
</BrowserRouter>
</div>
);
}
const-token=localStorage.getItem('token');
const PrivateRoute=({component,isAuthenticated,…rest}:any)=>{
常量路由组件=(道具:任意)=>(
认证
?React.createElement(组件、道具)
:
);
返回;
};
导出默认函数App(){
返回(
);
}
为什么要使用useState重定向?直接重定向即可。如果您使用的是react router
,最好使用useHistory
import { useHistory } from 'react-router-dom';
const history = useHistory();
useEffect(() => {
if(localStorage.getItem('token')){
history.push({
pathname: '/',
});
}
},[]);
如果您仍然想要使用useState,您可以创建一个新的useState,并将该状态添加到依赖项数组中
const history = useHistory();
useEffect(() => {
if(localStorage.getItem('token')){
setShouldRedirect(true);
}
},[]);
useEffect(() => {
if(shouldRedirect){
history.push({
pathname: '/',
});
}
},[shouldRedirect]);
我尝试使用您建议的第一种方法,但我的页面崩溃:
Error:Invalid hook call。钩子只能在函数组件的主体内部调用。发生这种情况的原因如下:1。React和渲染器(如React DOM)2的版本可能不匹配。你可能违反了Hooks 3的规则。在同一个应用程序中,您可能有多个React副本
事实上,只要我导入useHistory,我的visual studio文件就会开始显示一个黄点,当我初始化历史记录时,就会出现上面提到的错误。就这样crashes@a125在返回模板之前,需要将钩子放入组件函数中。