Javascript 使用aws amplify作为身份验证的PrivateRoute功能组件

Javascript 使用aws amplify作为身份验证的PrivateRoute功能组件,javascript,reactjs,react-router,aws-amplify,Javascript,Reactjs,React Router,Aws Amplify,我正在尝试创建与以下PrivateRoute类组件(源代码)等效的功能组件: import React,{useState,useffect}来自“React”; 从“react router dom”导入{Route,Redirect,withRouter,useHistory}; 从“aws放大”导入{Auth}; 类PrivateRoute扩展了React.Component{ 状态={ 加载:false, I验证:错误 }; componentDidMount(){ 这是authenti

我正在尝试创建与以下PrivateRoute类组件(源代码)等效的功能组件:

import React,{useState,useffect}来自“React”;
从“react router dom”导入{Route,Redirect,withRouter,useHistory};
从“aws放大”导入{Auth};
类PrivateRoute扩展了React.Component{
状态={
加载:false,
I验证:错误
};
componentDidMount(){
这是authenticate();
this.unlisten=this.props.history.listen(()=>{
Auth.currentAuthenticatedUser()
.then(user=>console.log(“user:,user))
.catch(()=>{
if(this.state.isAuthenticated)
this.setState({isAuthenticated:false});
});
});
}
组件将卸载(){
这是我的;
}
验证(){
Auth.currentAuthenticatedUser()
.然后(()=>{
this.setState({loaded:true,isAuthenticated:true});
})
.catch(()=>this.props.history.push(“/auth”);
}
render(){
const{component:component,…rest}=this.props;
const{loaded,isAuthenticated}=this.state;
如果(!loaded)返回空值;
返回(
{
返回是否经过验证(
) : (
);
}}
/>
);
}
}
使用路由器导出默认值(PrivateRoute);
当我这样使用应用程序时,上面的代码在我的应用程序中起作用:

<PrivateRoute
  exact
  path={urls.homepage}
  component={Homepage}
/>

我尝试将上述类组件转换为功能组件,如下所示:

import React, { useState, useEffect } from "react";
import { Route, Redirect, useHistory } from "react-router-dom";
import { Auth } from "aws-amplify";

const PrivateRoute = ({ component: Component, ...rest }) => {
  const [isLoaded, setIsLoaded] = useState(false);
  const [isAuthenticated, setIsAuthenticated] = useState(false);
  let history = useHistory();

  useEffect(() => {
    Auth.currentAuthenticatedUser()
      .then(() => {
        setIsLoaded(true);
        setIsAuthenticated(true);
      })
      .catch(() => history.push("/auth"));

    return () =>
      history.listen(() => {
        Auth.currentAuthenticatedUser()
          .then(user => console.log("user: ", user))
          .catch(() => {
            if (isAuthenticated) setIsAuthenticated(false);
          });
      });
  }, [history, isAuthenticated]);

  if (!isLoaded) return null;

  return (
    <Route
      {...rest}
      render={props => {
        return isAuthenticated ? (
          <Component {...props} />
        ) : (
          <Redirect
            to={{
              pathname: "/auth"
            }}
          />
        );
      }}
    />
  );
};

export default PrivateRoute;
import React,{useState,useffect}来自“React”;
从“react router dom”导入{Route,Redirect,useHistory};
从“aws放大”导入{Auth};
const privaterout=({component:component,…rest})=>{
const[isLoaded,setIsLoaded]=useState(false);
const[isAuthenticated,setIsAuthenticated]=useState(false);
让历史=使用历史();
useffect(()=>{
Auth.currentAuthenticatedUser()
.然后(()=>{
setIsLoaded(真);
setIsAuthenticated(真);
})
.catch(()=>history.push(“/auth”);
return()=>
历史。听(()=>{
Auth.currentAuthenticatedUser()
.then(user=>console.log(“user:,user))
.catch(()=>{
如果(isAuthenticated)设置为isAuthenticated(false);
});
});
},[历史,已认证];
如果(!isLoaded)返回null;
返回(
{
返回是否经过验证(
) : (
);
}}
/>
);
};
导出默认私有路由;
但是,当以同样的方式使用我的功能组件时,我不断得到以下错误:

警告:无法对已卸载的组件执行React状态更新。这是一个no-op,但它表示应用程序中存在内存泄漏。要修复此问题,请取消useEffect清理函数中的所有订阅和异步任务

无论我是否登录,它总是将我重定向到/auth。我做错了什么?非常感谢您的帮助

试试这个:

useEffect(() => {
  async function CheckAuth() {
    await Auth.currentAuthenticatedUser()
      .then((user) => {
        setIsLoaded(true);
        setIsAuthenticated(true);
      })
    .catch(() => history.push("/auth"));
  }
  CheckAuth();
}, []);

我认为您缺少卸载,在
useffect
中返回的应该是您的
unlisten
,即卸载。另外,我从道具中删除了
useHistory
并拉取
history
,然后使用路由器

试试这个

import React, { useState, useEffect } from "react";
import { Route, Redirect, withRouter } from "react-router-dom";
import { Auth } from "aws-amplify";

const PrivateRoute = ({ component: Component, history, ...rest }) => {
  const [isLoaded, setIsLoaded] = useState(false);
  const [isAuthenticated, setIsAuthenticated] = useState(false);

  useEffect(() => {
    Auth.currentAuthenticatedUser()
      .then(() => {
        setIsLoaded(true);
        setIsAuthenticated(true);
      })
      .catch(() => history.push("/auth"));
    
    const unlisten = history.listen(() => {
      Auth.currentAuthenticatedUser()
        .then(user => console.log("user: ", user))
        .catch(() => {
          if (isAuthenticated) setIsAuthenticated(false);
        });
    });

    return unlisten();
  }, [history, isAuthenticated]);

  if (!isLoaded) return null;

  return (
    <Route
      {...rest}
      render={props => {
        return isAuthenticated ? (
          <Component {...props} />
        ) : (
          <Redirect
            to={{
              pathname: "/auth"
            }}
          />
        );
      }}
    />
  );
};

export default withRouter(PrivateRoute);
import React,{useState,useffect}来自“React”;
从“react router dom”导入{Route,Redirect,withRouter};
从“aws放大”导入{Auth};
const privaterout=({component:component,history,…rest})=>{
const[isLoaded,setIsLoaded]=useState(false);
const[isAuthenticated,setIsAuthenticated]=useState(false);
useffect(()=>{
Auth.currentAuthenticatedUser()
.然后(()=>{
setIsLoaded(真);
setIsAuthenticated(真);
})
.catch(()=>history.push(“/auth”);
const unlisten=history.listen(()=>{
Auth.currentAuthenticatedUser()
.then(user=>console.log(“user:,user))
.catch(()=>{
如果(isAuthenticated)设置为isAuthenticated(false);
});
});
返回unlisten();
},[历史,已认证];
如果(!isLoaded)返回null;
返回(
{
返回是否经过验证(
) : (
);
}}
/>
);
};
使用路由器导出默认值(PrivateRoute);
import React, { useState, useEffect } from "react";
import { Route, Redirect, withRouter } from "react-router-dom";
import { Auth } from "aws-amplify";

const PrivateRoute = ({ component: Component, history, ...rest }) => {
  const [isLoaded, setIsLoaded] = useState(false);
  const [isAuthenticated, setIsAuthenticated] = useState(false);

  useEffect(() => {
    Auth.currentAuthenticatedUser()
      .then(() => {
        setIsLoaded(true);
        setIsAuthenticated(true);
      })
      .catch(() => history.push("/auth"));
    
    const unlisten = history.listen(() => {
      Auth.currentAuthenticatedUser()
        .then(user => console.log("user: ", user))
        .catch(() => {
          if (isAuthenticated) setIsAuthenticated(false);
        });
    });

    return unlisten();
  }, [history, isAuthenticated]);

  if (!isLoaded) return null;

  return (
    <Route
      {...rest}
      render={props => {
        return isAuthenticated ? (
          <Component {...props} />
        ) : (
          <Redirect
            to={{
              pathname: "/auth"
            }}
          />
        );
      }}
    />
  );
};

export default withRouter(PrivateRoute);