ReactJS-基于api调用响应的受保护路由

ReactJS-基于api调用响应的受保护路由,reactjs,react-hooks,local-storage,Reactjs,React Hooks,Local Storage,我正在尝试使用API端点实现受保护的路由,但与呈现相比,响应速度较慢。 因此,我的本地存储中有正确的数据,但react从不按时使用它们 我正在使用localStorage保存我的API身份验证响应,其中包含一个初始状态和一个调度器,用于在整个应用程序中更新我的状态 我从最高层所做的事情: 初始状态: export default { auth: {} }; App.js const App = () => { const [data, dispatch] = useReduc

我正在尝试使用API端点实现受保护的路由,但与呈现相比,响应速度较慢。
因此,我的本地存储中有正确的数据,但react从不按时使用它们

我正在使用localStorage保存我的API身份验证响应,其中包含一个初始状态和一个调度器,用于在整个应用程序中更新我的状态

我从最高层所做的事情:

初始状态:

export default {
  auth: {}
};  
App.js

const App = () => {
  const [data, dispatch] = useReducer(reducer, initialState);
  
  useEffect(() => {
    asyncStorage.getItem('data').then((storage) => {
      dispatch({ type: "PERSIST_DATA", payload: JSON.parse(storage) });
    });
  }, []);

  useEffect(() => {
    asyncStorage.setItem('data', JSON.stringify(data));
  }, [data]);
  
  return <Router data={data} dispatch={dispatch} />;
};
export default function Router({data, dispatch}) {
  
  return (
    <ProvideAuth data={data} dispatch={dispatch}>
      <BrowserRouter>
        <Switch>
            <PrivateRoute path="/" data={data} dispatch={dispatch}>
              <Home data={data} dispatch={dispatch} />
            </PrivateRoute>
            <Route path="/sign-in" render={() => <Signin data={data} dispatch={dispatch} /> } />
          </Switch>
      </BrowserRouter>
    </ProvideAuth>
  )

} 

function PrivateRoute({ children, ...rest }) {
  const auth = useAuth()
  
  return (
    <Route {...rest} render={({ location }) =>
        auth.loggedIn ? (children) :
        (<Redirect to={{ pathname: '/sign-in', state: { from: location } }} />)
      }
    />
  )
}
const authContext = createContext();

export function ProvideAuth({ children, data, dispatch }) {
  const auth = useProvideAuth(data, dispatch)
  return <authContext.Provider value={auth}> { children } </authContext.Provider>
}

export const useAuth = () => useContext(authContext);

function useProvideAuth(data, dispatch) {
  const [loggedIn, setLoggedIn] = useState(null);
  
  useEffect(() => {
    auth
      .me(dispatch)
      .then(() => {
        setLoggedIn(true);
      })
      .catch(() => {
        setLoggedIn(false)
      });
  }, [])

  return {
    loggedIn
  }

}

我觉得我快到了,但我可能错过了一些明显的东西。

No 1:我相信,你在App.js中的第二个useEffect几乎每秒钟都会运行一次,因为没有指定依赖项数组,这可能会影响你期望的更新,因为组件一直在装载


第二:我不知道auth.js中的auth.me(dispatch)是做什么的,所以很难推断Second useffect只运行一次。比如说,在浏览器刷新后,我找不到另一种保存数据的方法。auth.me请求API并用电子邮件更新localStorage状态。如果是这样,为什么不先使用console.log(auth.loggedIn)查看它是false还是true。您可以确认您的状态是否真的更新到TrueT,正如我提到的,问题是页面重定向到登录后确实会更新。我无法给出最佳解决方案,因为我看不到工作代码,但我认为如果您在重定向到登录页面后将auth.loggedin设置为true,那么这应该可以工作,我认为您只需要在登录页面中添加一个useEffect,检查auth.logged-in是否为true并重定向到主页。如果我只是在SignIn组件后面添加相同的逻辑,它将在每次导航单击后在登录表单上重定向。我很惊讶没有通用的方法来做这件事。
export function me(dispatch) {
  return api
    .me()
    .then((response) => {
      dispatch({ type: "UPDATE_AUTH", payload: response });
    })
    .catch((error) => {
      throw error;
    });
}