как сделать так, чтобы компонент не возвращался до завершения асинхронной функции?

# #reactjs #firebase #react-redux #firebase-authentication

#реагирует на #огневая база #реагировать-переделывать #firebase-аутентификация

Вопрос:

я пытаюсь создать частный маршрут.моя идея состоит в том, чтобы проверить, вошел пользователь в систему или нет в App.jsx, и сохранить это состояние с помощью redux.

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

в моем магазине я изменю состояние на основе реквизитов, которые предоставляет 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  }  ...  },  

в моем личном маршруте,если пользователь вошел в систему, я направляюсь к компонентам и перехожу на страницу входа, если нет.

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

но я столкнулся с ошибкой, когда веб-перезагрузка(F5) , все состояние в хранилище было сброшено,и приватный маршрут был запущен до завершения метода onAuthStateChanged,так что в любом случае для моей проблемы?

спасибо за помощь и всем хорошего дня!

Ответ №1:

Используйте библиотеку redux-persist для хранения информации о пользователе LoggedIn в локальном хранилище. Что — то вроде этого:

 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)) );  lt;Provider store={store}gt;  lt;PersistGate persistor={persistStore(store)}gt;  lt;App /gt;  lt;/PersistGategt; lt;/Providergt;  

Комментарии:

1. о, большое спасибо, я им воспользуюсь

2. Повторное сохранение работает хорошо, но вы можете рассмотреть возможность сохранения состояния в хранилище сеансов вместо локального хранилища

3. @Bugbeeb Да, если вы хотите очистить данные после закрытия браузера, вы также можете использовать хранилище сеансов