最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to perform authentication with React hooks and react-router - Stack Overflow

programmeradmin0浏览0评论

I am trying to authenticate user on each route change with react-router-dom and react hooks. The idea is that each time user navigates to a route the system makes an api call and authenticate the user. I need to achieve this because I use react-redux, and on each window reload the redux state is not persisted. So i need to set the isLoggedNow prop to true again:

const PrivateRoute = ({
  ponent: Component,
  checkOnEachRoute: checkReq,
  isUserLogged,
  ...rest
}) => {
  const [isLoggedNow, setLogged] = useState(isUserLogged);
  useEffect(
    () => {
      const fetchStatus = async () => {
        try {
          await selectisUserLogged();
          setLogged(true);
        } catch (error) {
          console.log(error);
        }
      };
      fetchStatus();
    },
    [isUserLogged],
  );
  return (
    <Route
      {...rest}
      render={props =>
        isLoggedNow ? (
          <div>
            <Component {...props} />
          </div>
        ) : (
          <Redirect
            to={{
              pathname: '/login',
            }}
          />
        )
      }
    />
  );
};

I then would use the above PrivateRoute like this:

function App(props) {
  return (
    <div>
      <Switch location={props.location}>
        <Route exact path="/login" ponent={Login} />
        <PrivateRoute exact path="/sidebar" ponent={Sidebar} />
      </Switch>
    </div>
  );
}

First the isUserLogged is true, but after window reload I get an error Warning: Can't perform a React state update on an unmounted ponent. So how can I achieve this, so on each window reload I authenticate the user? I am looking for some kind of ponentWillMount.

I am trying to authenticate user on each route change with react-router-dom and react hooks. The idea is that each time user navigates to a route the system makes an api call and authenticate the user. I need to achieve this because I use react-redux, and on each window reload the redux state is not persisted. So i need to set the isLoggedNow prop to true again:

const PrivateRoute = ({
  ponent: Component,
  checkOnEachRoute: checkReq,
  isUserLogged,
  ...rest
}) => {
  const [isLoggedNow, setLogged] = useState(isUserLogged);
  useEffect(
    () => {
      const fetchStatus = async () => {
        try {
          await selectisUserLogged();
          setLogged(true);
        } catch (error) {
          console.log(error);
        }
      };
      fetchStatus();
    },
    [isUserLogged],
  );
  return (
    <Route
      {...rest}
      render={props =>
        isLoggedNow ? (
          <div>
            <Component {...props} />
          </div>
        ) : (
          <Redirect
            to={{
              pathname: '/login',
            }}
          />
        )
      }
    />
  );
};

I then would use the above PrivateRoute like this:

function App(props) {
  return (
    <div>
      <Switch location={props.location}>
        <Route exact path="/login" ponent={Login} />
        <PrivateRoute exact path="/sidebar" ponent={Sidebar} />
      </Switch>
    </div>
  );
}

First the isUserLogged is true, but after window reload I get an error Warning: Can't perform a React state update on an unmounted ponent. So how can I achieve this, so on each window reload I authenticate the user? I am looking for some kind of ponentWillMount.

Share Improve this question edited May 14, 2019 at 8:35 skyboyer 23.8k7 gold badges62 silver badges71 bronze badges asked Mar 26, 2019 at 13:53 user1665355user1665355 3,3939 gold badges47 silver badges86 bronze badges 4
  • did you have a chance to resolve this issue? – genesst Commented May 14, 2019 at 11:47
  • @camelCase yes! – user1665355 Commented May 14, 2019 at 11:47
  • care to share? :) facing exact same issue at the moment – genesst Commented May 14, 2019 at 11:51
  • @camelCase See my answer, does it solve it for you?:) – user1665355 Commented May 14, 2019 at 11:53
Add a ment  | 

1 Answer 1

Reset to default 6

Something like this works (where isUserLogged is a prop from redux):

function PrivateRoute({ ponent: Component, isUserLogged, ...rest }) {
  const [isLoading, setLoading] = useState(true);
  const [isAuthenticated, setAuth] = useState(false);
  useEffect(() => {
    const fetchLogged = async () => {
      try {
        setLoading(true);
        const url = new URL(fetchUrl);
        const fetchedUrl = await fetchApi(url);
        setAuth(fetchedUrl.body.isAllowed);
        setLoading(false);
      } catch (error) {
        setLoading(false);
      }
    };
    fetchLogged();
  }, []);
  return (
    <Route
      {...rest}
      render={props =>
        // eslint-disable-next-line no-nested-ternary
        isUserLogged || isAuthenticated ? (
          <Component {...props} />
        ) : isLoading ? (
          <Spin size="large" />
        ) : (
          <Redirect
            to={{
              pathname: '/login',
            }}
          />
        )
      }
    />
  );
}
发布评论

评论列表(0)

  1. 暂无评论