У меня проблема после обновления до 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;
}
};
У меня есть несколько проблем
Свойства в компонентах перестали обновляться, однако все саги, редукторы вызываются и статистикаизменилось, однако я не могу обновить свои компоненты.
Чтобы получить обработанный маршрут, мне нужно обновить всю страницу, если, например, маршрут был изменен с помощью перенаправления или нажмите егоне отображает никаких компонентов.
Пожалуйста, помогите решить проблему, я занимался этим целый день.
Ценю любую помощь