【问题标题】:how to make component don't return until async function complete?如何使组件在异步功能完成之前不返回?
【发布时间】:2022-01-05 02:30:07
【问题描述】:

我正在尝试创建一个私有路由。我的想法是检查用户是否在 App.jsx 中登录并使用 redux 存储此状态。

import {getAuth,onAuthStateChanged} from "firebase/auth"
...
function App() {
  const auth = getAuth();
  const dispatch = useDispatch()
 
  
  useEffect(()=>{
    async function stateChanged(){
      await onAuthStateChanged(auth, (user) => {
        if (user) {
         dispatch(checkState(true))
        } else {
         dispatch(checkState(false))
        }
      });
    }
    stateChanged()
  },[dispatch,auth])
  return (
    <Routes>
    <Route
      path="/login"
      element={<Auth authRoute="login"/> }
    />
    <Route
      path="/details"
      element={<PrivateRoute component={UserDetailsProfile}/>}
    />
    ...
  </Routes>
  );
}

在我的商店中,我将根据 onAuthStateChanged 提供的道具更改状态

const authSlice = createSlice({
  name: "auth",
  initialState: {
    auth: {
      isLoading: false,
      isAuthenticate: false,
      user: {...User},
    },
  },
  reducers: {
    checkState(state,action){
      if(state.auth.isLoading) state.auth.isLoading = false
      state.auth.isAuthenticate = action.payload
    }
  ...
  },

在我的 PrivateRoute 中,如果用户登录,我会路由到组件并导航到登录页面,如果没有。

const PrivateRoute = ({component:Component,...rest}) => {
   
    const {isLoading,isAuthenticate} = useSelector(authSelector)
    if (isLoading)
    return (
        <div className='spinner-container'>
            <Spinner animation='border' variant='info' />
        </div>
    )
    return isAuthenticate ? (<Component/>) :(<Navigate to="/login"/>) 
}

但是我遇到了一个错误,当网络重新加载(F5) 时,商店的所有状态都被重置,并且 PrivateRoute 在 onAuthStateChanged 方法完成之前运行,所以我的问题还有吗?

感谢大家的帮助,祝大家有个愉快的一天!

【问题讨论】:

    标签: reactjs firebase react-redux firebase-authentication


    【解决方案1】:

    使用 redux-persist 库将已登录的用户信息保存在 localStorage 中。 像这样的:

    import { persistStore, persistReducer } from 'redux-persist';
    import storage from 'redux-persist/lib/storage';
    import userReducer from './userReducer';
    import { Provider } from 'react-redux';
    import { PersistGate } from 'redux-persist/integration/react';
    
    const persistConfig = {
      key: 'root',
      storage,
      whitelist: ['isAuthenticate'],
    };
    
    const persistedReducer = persistReducer(persistConfig, userReducer);
    
    const store = createStore(
        persistedReducer,
        initialState,
        composeEnhancers(applyMiddleware(thunk))
    );
    
    <Provider store={store}>
        <PersistGate persistor={persistStore(store)}>
            <App />
        </PersistGate>
    </Provider>
    

    【讨论】:

    • 非常感谢,我会用它
    • Redux persist 运行良好,但您可能需要考虑将状态保存到会话存储而不是本地存储
    • @Bugbeeb 是的,如果你想在关闭浏览器后清除数据,你也可以使用会话存储
    猜你喜欢
    • 1970-01-01
    • 2020-10-10
    • 2017-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多