Javascript UseEffect()不断为重定向提供错误

Javascript UseEffect()不断为重定向提供错误,javascript,reactjs,typescript,react-router,react-hooks,Javascript,Reactjs,Typescript,React Router,React Hooks,如果登录成功,将返回一个令牌并将其存储在本地存储器中。在这种情况下,我应该重定向到专用路由/配线架。如果登录失败,我应该能够显示来自ShowError()的错误消息。在我添加重定向之前,错误消息功能工作正常 这是我的LoginPage.tsx function LoginPage (){ const [state, setState] = useState({ email: '', password: '', }); const [submitted, setSub

如果登录成功,将返回一个令牌并将其存储在本地存储器中。在这种情况下,我应该重定向到专用路由/配线架。如果登录失败,我应该能够显示来自
ShowError()
的错误消息。在我添加重定向之前,错误消息功能工作正常

这是我的LoginPage.tsx

function LoginPage (){
  const [state, setState] = useState({
    email: '',
    password: '',
  }); 

 const [submitted, setSubmitted] = 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(){
  if(submitted && localStorage.getItem('token')){
    return <Redirect to='/panel'/>
  }
}

// useEffect(() => {
//   if(localStorage.getItem('token')){
//     return <Redirect to='/panel'/>
//   }
// },[] );

  function submitForm(LoginMutation: any) {
    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);FormSubmitted();RedirectionToPanel()}}>
                      <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>
            {submitted && <Redirect to='/panel'/>}
          </Container>
          )
        }
      </Mutation>
    );
}

export default LoginPage;
下面是如何在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}/>;
};

const token=localStorage.getItem('token');
const PrivateRoute=({component,isAuthenticated,…rest}:any)=>{
常量路由组件=(道具:任意)=>(
认证
?React.createElement(组件、道具)
: 
);
回来
};
如果我注释掉
{submitted&&}
,我会在登录失败时收到错误消息,但即使登录成功,也不会重定向

编辑的代码:

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);RedirectionToPanel()}}>
                      <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>
                    </form>
                  )
                }}
              </Formik>
            </div>
            {/* {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(LoginMutate);RedirectionToPanel()}>
{已提交(&R)}

提交 ) }} {/*{已提交&}*/} ) } ); } 导出默认登录页面;
我认为返回的
重定向
组件不应该在
useffect
hook或任何函数中调用。 你应该有这样的东西:

function LoginPage (){
  const [state, setState] = useState({
    email: '',
    password: '',
  }); 
  const [shouldRedirect, setShouldRedirect] = useState(false);

  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);
       setShouldRedirect(true);
     })
    .catch(console.log)
   }
  }
  if(shouldRedirect) return <Redirect to="/panel" />;
  return (
   ... rest of code
  );
}
函数登录页(){
常量[状态,设置状态]=使用状态({
电子邮件:“”,
密码:“”,
}); 
const[shouldRedirect,setShouldRedirect]=useState(false);
useffect(()=>{
if(localStorage.getItem(“令牌”)){
setShouldRedirect(true);
}
}, []);
函数提交形式(LoginMutation:any){
setSubmitted(true);
const{email,password}=state;
如果(电子邮件和密码){
逻辑置换({
变量:{
电邮:电邮,,
密码:密码,
},
})。然后({data}:any)=>{
localStorage.setItem('token',data.loginEmail.accessToken);
setShouldRedirect(true);
})
.catch(console.log)
}
}
如果(应该重定向)返回;
返回(
…代码的其余部分
);
}

我认为返回的
重定向
组件不应该在
useffect
hook或任何函数中调用。 你应该有这样的东西:

function LoginPage (){
  const [state, setState] = useState({
    email: '',
    password: '',
  }); 
  const [shouldRedirect, setShouldRedirect] = useState(false);

  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);
       setShouldRedirect(true);
     })
    .catch(console.log)
   }
  }
  if(shouldRedirect) return <Redirect to="/panel" />;
  return (
   ... rest of code
  );
}
函数登录页(){
常量[状态,设置状态]=使用状态({
电子邮件:“”,
密码:“”,
}); 
const[shouldRedirect,setShouldRedirect]=useState(false);
useffect(()=>{
if(localStorage.getItem(“令牌”)){
setShouldRedirect(true);
}
}, []);
函数提交形式(LoginMutation:any){
setSubmitted(true);
const{email,password}=state;
如果(电子邮件和密码){
逻辑置换({
变量:{
电邮:电邮,,
密码:密码,
},
})。然后({data}:any)=>{
localStorage.setItem('token',data.loginEmail.accessToken);
setShouldRedirect(true);
})
.catch(console.log)
}
}
如果(应该重定向)返回;
返回(
…代码的其余部分
);
}

您能否在qs中查看我编辑的代码,并指导我在我的案例中使用
if(shouldRedirect)
语句?如果我在返回值上方使用它,它会给出一个错误。@a125在返回值上方使用它时会出现什么错误?
编译失败/src/pages/login/LoginPage.tsx第269:24行:应为赋值或函数调用,而不是sa