Как эффективно защитить маршруты в сочетании с реакции-роутером и паспортом на бэкэнде - PullRequest
1 голос
/ 20 апреля 2019

У меня есть React и Node.js с passport.js на бэкэнде, который реализует аутентификацию моего приложения.Моя реакция вызывает мой бэкэнд и выбирает авторизованного пользователя через редуктор действий.Все работает нормально, но есть проблема с охраной маршрута.Вот как я защищаю маршруты, если пользователь не вошел в систему

, если (! This.props.auth) вернул

Проблема в том, когда пользователь вошел в систему, если страницаПри обновлении приведенный выше код выполняется быстрее, чем mapStateToProps возвращает авторизованного пользователя, а зарегистрированный пользователь перенаправляется на страницу индекса.Это плохой пользовательский опыт.Пожалуйста, помогите мне, как решить эту проблему, и я был бы признателен за помощь и совет.

Я думаю, что мне нужно сделать, чтобы убедиться, что хранилище обновляется в первую очередь, прежде чем рендерится DOM, но я не уверен, как это сделать.

Вот панель управления

 class Dashboard extends Component {
 render() {
 if(!this.props.auth) return <Redirect to='/' /> 
 if (!this.props.auth.googleUsername) {
  return <div className='container'> Loading ... </div>;
} else {
  return (
    <div className='container' style={{ margin: '10px 10px' }}>
       {this.props.auth.googleUsername}
    </div>
    );
}
 function mapStateToProps({auth}) {
 return {auth};
}
 export default connect(mapStateToProps)(Dashboard);

Вот App.js

import { connect } from 'react-redux';
import { fetchUser } from './store/actions/index';
import Home from './components/layout/Home';
import Dashboard from './components/layout/Dashboard';

 class App extends Component {

  componentDidMount() {
  this.props.fetchUser();
   } 
    render() {
   return (
    <div>
     <BrowserRouter>
      <div>
        <Header />
        <Switch>
        <Route exact path='/' component={Home} />
        <Route path='/dashboard' component={Dashboard} />
        </Switch>
      </div>
    </BrowserRouter>
    </div>
    );
  }
 }
  export default connect(null,{ fetchUser })(App)

Действие редуктора

  import axios from 'axios';
  import { FETCH_USER } from './types';
  export const fetchUser =  () => async dispatch => {
  const res = await axios.get('/api/current_user');
  dispatch({ type: FETCH_USER, payload: res.data });
  };

Auth Reducer

 import { FETCH_USER } from '../actions/types';
 export default function(state = false, action) {
 switch (action.type) {
    case FETCH_USER:
      return action.payload;
  default:
  return state;
  }
 }

1 Ответ

1 голос
/ 27 апреля 2019

Для тех, у кого есть эта проблема, мне удалось решить вероятное.Проблема заключалась в том, что мне нужно сохранить избыточное хранилище в моем приложении.Я использовал стороннюю библиотеку под названием 'redux-persist'

Вот набор, который я использовал в моем index.js

import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import rootReducer from './store/reducers/rootReducer';
import thunk from 'redux-thunk';
import { persistStore, persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage'; 
import { PersistGate } from 'redux-persist/integration/react';

const persistConfig = {
key: 'root',
storage,
}
   const persistedReducer = persistReducer(persistConfig, rootReducer)
   const store = createStore(persistedReducer, applyMiddleware(thunk));
   const persistor = persistStore(store);

  ReactDOM.render(
    <Provider store={store}>
     <PersistGate loading={null} persistor={persistor}>
       <App />
     </PersistGate>
    </Provider>,
   document.getElementById('root'));
...