После обновления до реакции-редукса 6 свойства обновляются, но рендеринг не срабатывает - PullRequest
0 голосов
/ 22 декабря 2018

У меня проблема после обновления до react-redux 6.Похоже, что хранилище приставок работает должным образом, но компоненты не получают обновлений при изменении состояния.

Вот мой index.tsx

const store = getReduxStore();
const devTools = process.env.NODE_ENV === 'development' ? <DevTools store={store}/> : null;
registerLocale(store);
setupAxiosInterceptors(() => getReduxStore().dispatch(AuthActions.onUnauthorizedRequest()));

const rootEl = document.getElementById('root');

const render = Component =>
  ReactDOM.render(
    <ErrorBoundary>
      <AppContainer>
        <DiProvider container={getRootDiContainer()}>
          <Provider store={store}>
            <ConnectedRouter history={history}>
              {/*     <Startup>*/}
              <div>
                {/* If this slows down the app in dev disable it and enable when required  */}
                {/*   {devTools}*/}
                <Component/>
              </div>
              {/*         </Startup>*/}
            </ConnectedRouter>
          </Provider>
        </DiProvider>
      </AppContainer>
    </ErrorBoundary>,
    rootEl
  );
render(AppComponent);
// Hot Module Replacement API
if (module.hot) {
  module.hot.accept('./app', () => {
    const AppMain = AppComponent;
    render(AppMain);
  });
}
registerServiceWorker();

Мой основной компонент app.tsx

export class App extends React.Component<IAppProps> {
  componentDidMount() {
    this.props.getSession();
  }

  render() {
    const {notifications} = this.props;
    return (
      <div className="app-container">
        <LoadingBar showFastActions={false} updateTime={50} style={{backgroundColor: '#009cd8', height: '4px', zIndex: 999999}}/>
        <Notifications notifications={notifications} style={notificationsStyle}/>
        <ToastContainer
          position={toast.POSITION.TOP_LEFT as ToastPosition}
          className="toastify-container"
          toastClassName="toastify-toast"
        />
        <ErrorBoundary>
          <ThemeProvider theme={themes[themeConfig.theme]}>
            <DashAppHolder>
              <PublicRoutes history={history}/>
            </DashAppHolder>
          </ThemeProvider>
        </ErrorBoundary>
      </div>
    );
  }
}

const mapStateToProps = ({authentication, notifications, locale}: IRootState) => ({
  currentLocale: locale.currentLocale,
  isAuthenticated: authentication.isAuthenticated,
  notifications,
  isAdmin: isAdmin(authentication.account.authorities)
});

const mapDispatchToProps = {
  setLocale: LocaleActions.setLocale,
  getSession: AuthActions.getSession,
  showLoading
};

type StateProps = ReturnType<typeof mapStateToProps>;
type DispatchProps = typeof mapDispatchToProps;

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(App);

Мой главный router.tsx

const PublicRoutes = ({history, isLoggedIn}) => {
  return (
    <div>
      <Route exact path={'/'} render={() => <Redirect to="/login"/>}/>
      <Route exact path={'/404'} component={asyncComponent(() => import('app/modules/404/404'))}/>
      <Route exact path={'/500'} component={asyncComponent(() => import('app/modules/500/500'))}/>
      <Route exact path={'/login'} component={asyncComponent(() => import('app/modules/login/page/LoginPage.tsx'))}/>
      <RestrictedRoute path="/dashboard" component={asyncComponent(() => import('app/modules/dashboard/page/Dashboard'))} isLoggedIn={isLoggedIn}/>
    </div>
  );
};

export default connect(({authentication}: IRootState) => ({
  isLoggedIn: authentication.isAuthenticated
}))(PublicRoutes);

И мой магазин создается следующим образом

import { applyMiddleware, compose, createStore } from 'redux';
import promiseMiddleware from 'redux-promise-middleware';
import getRootReducers, { IRootState } from 'app/shared/reducers';
import DevTools from './devtools';
import errorMiddleware from './error-middleware';
import notificationMiddleware from './notification-middleware';
import loggerMiddleware from './logger-middleware';
import { loadingBarMiddleware } from 'react-redux-loading-bar';
import createSagaMiddleware from 'redux-saga';
import rootSaga from 'app/config/saga';
import createBrowserHistory from 'history/createBrowserHistory';

const sagaMiddleware = createSagaMiddleware();
const defaultMiddlewares = [
  errorMiddleware,
  notificationMiddleware,
  promiseMiddleware(),
  loadingBarMiddleware({
    promiseTypeSuffixes: ['REQUEST', 'SUCCESS', 'FAILURE']
  }),
  loggerMiddleware,
  sagaMiddleware
];
export const history = createBrowserHistory();
const composedMiddlewares = middlewares =>
  process.env.NODE_ENV === 'development'
    ? compose(
    applyMiddleware(...defaultMiddlewares, ...middlewares),
    DevTools.instrument()
    )
    : compose(applyMiddleware(...defaultMiddlewares, ...middlewares));

const initialize = (initialState?: IRootState, middlewares = []) => {
  // @ts-ignore
  const rootReducers = getRootReducers(history);
  // @ts-ignore
  const store = createStore(rootReducers, initialState, composedMiddlewares(middlewares));
  sagaMiddleware.run(rootSaga);
  return store;
};
export const getReduxStore = (() => {
  let store = null;

  return () => {
    if (!store) {
      store = initialize();
    }
    return store;
  };
})();

Редукторы определяются следующим образом

export interface IRootState {
  readonly authentication: AuthenticationState;
  readonly app: AppState;
  readonly locale: LocaleState;
  readonly administration: AdministrationState;
  readonly userManagement: UserManagementState;
  readonly register: RegisterState;
  readonly activate: ActivateState;
  readonly passwordReset: PasswordResetState;
  readonly password: PasswordState;
  readonly settings: SettingsState;
  readonly notifications: any;
  readonly loadingBar: any;
  /* jhipster-needle-add-reducer-type - JHipster will add reducer type here */
  readonly LanguageSwitcher: any;
  readonly Mails: any;
  readonly Calendar: any;
  readonly Box: any;
  readonly Notes: any;
  readonly Todos: any;
  readonly Contacts: any;
  readonly Cards: any;
  readonly Chat: any;
  readonly DynamicChartComponent: any;
  readonly Ecommerce: any;
  readonly Invoices: any;
  readonly YoutubeSearch: any;
  readonly Articles: any;
  readonly router: any;
  readonly Investors: any;
}

export const getRootCombinedReducers = ((): Reducer<IRootState> => {
  let rootReducers = null;
  return (history) => {
    if (!rootReducers) {
      rootReducers = combineRootReducers(history);
    }
    return rootReducers;
  };
})();

export const combineRootReducers = (history): Reducer<IRootState> => {
  return combineReducers<IRootState>({
    authentication,
    app,
    locale,
    administration,
    userManagement,
    register,
    activate,
    passwordReset,
    password,
    settings,
    loadingBar,
    notifications,
    router: connectRouter(history),
    LanguageSwitcher,
    Mails,
    Calendar,
    Box,
    Notes,
    Todos,
    Contacts,
    Cards,
    Chat,
    DynamicChartComponent,
    Ecommerce,
    Invoices,
    YoutubeSearch,
    Articles,
    Investors
  });
};

export default getRootCombinedReducers;

Мой аутентификационный редуктор

export const ACTION_TYPES = {
  LOGIN: 'authentication/LOGIN',
  GET_SESSION: 'authentication/GET_SESSION',
  LOGOUT: 'authentication/LOGOUT',
  CLEAR_AUTH: 'authentication/CLEAR_AUTH',
  ERROR_MESSAGE: 'authentication/ERROR_MESSAGE',
  UNAUTHORIZED_ERROR: 'authentication/ERROR_UNAUTHORIZED'
};

const initialState = {
  isAuthenticated: false,
  loginSuccess: false,
  loginInProcess: false,
  loginError: false, // Errors returned from server side
  account: {} as any,
  sessionHasBeenFetched: false
};

export type AuthenticationState = Readonly<typeof initialState>;

// Reducer

export default (state: AuthenticationState = initialState, action): AuthenticationState => {
  switch (action.type) {
    case REQUEST(ACTION_TYPES.LOGIN):
      return {
        loginInProcess: true,
        ...state
      };
    case FAILURE(ACTION_TYPES.LOGIN):
      return {
        ...initialState,
        loginInProcess: false,
        sessionHasBeenFetched: false,
        isAuthenticated: false
      };
    case FAILURE(ACTION_TYPES.GET_SESSION):
      return {
        ...state,
        isAuthenticated: false,
        sessionHasBeenFetched: true
      };
    case SUCCESS(ACTION_TYPES.LOGIN):
      return {
        ...state,
        loginInProcess: false,
        isAuthenticated: true,
        sessionHasBeenFetched: false,
        loginError: false,
        loginSuccess: true
      };
    case ACTION_TYPES.LOGOUT:
      return {
        ...initialState
      };
    case SUCCESS(ACTION_TYPES.GET_SESSION):
      const isAuthenticated = action.payload && action.payload.activated;
      return {
        ...state,
        isAuthenticated,
        sessionHasBeenFetched: true,
        account: action.payload
      };
    default:
      return state;
  }
};

У меня есть несколько проблем

  1. Свойства в компонентах перестали обновляться, однако все саги, редукторы вызываются и статистикаизменилось, однако я не могу обновить свои компоненты.

  2. Чтобы получить обработанный маршрут, мне нужно обновить всю страницу, если, например, маршрут был изменен с помощью перенаправления или нажмите егоне отображает никаких компонентов.

Пожалуйста, помогите решить проблему, я занимался этим целый день.

Ценю любую помощь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...