1

我想实现受保护的路由,并使用 firebase 进行身份验证。我的浏览器被这段代码冻结:

const App: React.FC = () => {
  const [authentication, setAuthState] = useState({
    authenticated: false,
    initializing: true
  });

  firebase.auth().onAuthStateChanged(user => {
    if (user) {
      setAuthState({
        authenticated: true,
        initializing: false
      });
    } else {
      setAuthState({
        authenticated: false,
        initializing: false
      });
    }
  });

  if (authentication.initializing) {
    return <div>Loading</div>;
  }
  return (
    <Router>
      <div>
        <Switch>
          <Route exact path="/login" component={Login} />
          <PrivateRoute
            path="/"
            component={Home}
            authenticated={authentication.authenticated}
          />
          <PrivateRoute
            path="/join"
            component={Join}
            authenticated={authentication.authenticated}
          />
          <PrivateRoute
            path="/create"
            component={Create}
            authenticated={authentication.authenticated}
          />
        </Switch>
      </div>
    </Router>
  );
};

我是 React 新手,这是我第一次使用 React 钩子,但这里有什么问题?

4

1 回答 1

7

我认为就像 iHowell 在评论中解释的那样,firebase auth ... 是一个副作用,所以你必须使用 useEffect 钩子。

const App: React.FC = () => {
  const [authentication, setAuthState] = useState({
    authenticated: false,
    initializing: true
  });

  React.useEffect(() => firebase.auth().onAuthStateChanged(user => {
    if (user) {
      setAuthState({
        authenticated: true,
        initializing: false
      });
    } else {
      setAuthState({
        authenticated: false,
        initializing: false
      });
    }
  }), [setAuthState]);

  if (authentication.initializing) {
    return <div>Loading</div>;
  }
  return (
    <Router>
      <div>
        <Switch>
          <Route exact path="/login" component={Login} />
          <PrivateRoute
            path="/"
            component={Home}
            authenticated={authentication.authenticated}
          />
          <PrivateRoute
            path="/join"
            component={Join}
            authenticated={authentication.authenticated}
          />
          <PrivateRoute
            path="/create"
            component={Create}
            authenticated={authentication.authenticated}
          />
        </Switch>
      </div>
    </Router>
  );
};
于 2019-11-08T15:29:33.550 回答