У меня были довольно старые зависимости в моем проекте, поэтому я решил обновить их все.Проблема, с которой я столкнулся, была связана с горячим загрузчиком React.Теперь горячая загрузка отлично работает с моим компонентом приложения, который я украшаю горячим (модуль) (приложение).В других компонентах / маршрутах горячая загрузка работает, но сбрасывает все состояния редукторов, в результате веб-приложение перенаправляет на страницу входа в систему, поскольку auth
prop сбрасывается и никогда не изменяется.
Компонент приложения:
class App extends Component {
state={
loggedIn:false,
state1:false,
state2:false,
state3:false,
}
componentDidUpdate(prevProps) {
console.log('apploggedIn', this.props.loggedIn, prevProps.loggedIn)
this.props.loggedIn!==prevProps.loggedIn&&this.setState({loggedIn:this.props.loggedIn})
}
componentDidMount() {
// console.log('didmount', this.props)
this.props.token&&this.props.dispatch(actions.getAttornies(this.props.token))
this.props.token&&this.props.dispatch(actions.getProviderList(this.props.token))
}
componentWillMount() {
this.props.dispatch(actions.isLoggedIn())
componentWillReceiveProps(nextProps) {
console.log('nextprops',nextProps)
if (this.props.token!==nextProps.token) {
nextProps.token&&nextProps.dispatch(actions.getAttornies(nextProps.token))
nextProps.token&&nextProps.dispatch(actions.getProviderList(nextProps.token))
}
}
onUnload(){
this.props.router.push('/')
}
onLogin(e) {
this.props.dispatch(actions.signIn(e.login,e.password))
}
render() {
const { location, children, dispatch, loggedIn, alert } = this.props;
console.log("AppProps", this.props)
return <div className="vbox container-fluid">
<div className="row">
<section className="hbox stretch" style={{width:'100%', background:'#f3f4f8'}}>
<section id="content">
<Header
router={this.props.history}
dispatch={this.props.dispatch}
openModal={(e)=>this.openModal(e)}/>
<div className="row"
>
<div className="col-12" style={{minHeight:'90vh'}}>
<Switch>
<PrivateRoute exact path="/" component={Startpage} />
<Route
component={PatientSearch}
path="/patient/search"
/>
<PrivateRoute
component={Technician}
path="/technician"
/>
<Route
component={Login}
path="/login"
/>
<Route
component={Analytics}
path="/analytics"
/>
<Route
component={Notes}
path="/notes"
/>
<Route
component={DeliveryReports}
path="/delivery_reports"
/>
</Switch>
</div>
</div>
</section>
</section>
</div>
</div>
}
// }
}
const mapStateToProps=(state)=>{
return {
loggedIn: state.app.loggedIn,
token: state.app.token,
isLoading: state.loading.loading,
alert:state.alert
};
}
export default withRouter(connect(mapStateToProps)(hot(module)(App)));
Корневой компонент:
const store = configureStore(/* provide initial state if any */)
const PrivateRoute = ({ component: Component, authed, ...rest }) => (
<Route {...rest} render={(props) => (
authed === true
? <Component {...props} />
: <Redirect to={{
pathname: '/login',
state: { from: props }
}} />
)} />
)
class Root extends Component {
state = {loggedIn:false}
render() {
return (
<Provider store={store}>
<ConnectedRouter history={history}>
<Router >
<App>
</App>
</Router>
</ConnectedRouter>
</Provider>
);
}
}
export default (Root)
Компонент наименьшего уровня index.js
import "babel-polyfill";
import React from 'react';
import ReactDOM from 'react-dom';
import Root from './containers/Root';
import configureStore from './store/configureStore'
import { AppContainer } from 'react-hot-loader';
const store = configureStore();
const render = Component => {
ReactDOM.render(
<AppContainer>
<Component />
</AppContainer>,
document.getElementById('wrapperContainer'),
);
};
render(Root)
if (module.hot) {
module.hot.accept('./containers/Root', () => {
const NextRootContainer = require('./containers/Root').default;
render(NextRootContainer);
});
}
Настройка части магазина:
import { createStore, applyMiddleware, combineReducers, compose } from 'redux';
import thunkMiddleware from 'redux-thunk';
import { connectRouter } from 'connected-react-router'
import promiseMiddleware from '../middleware/promiseMiddleware';
import loggerMiddleware from 'redux-logger';
import * as reducers from '../reducers/';
import { reducer as formReducer } from 'redux-form'
import app from '../reducers/app'
import {createBrowserHistory} from "history";
export const history = createBrowserHistory()
const reducer = combineReducers({...reducers.default, router:connectRouter(history), form:formReducer });
const createStoreWithMiddleware = applyMiddleware(
thunkMiddleware,
promiseMiddleware
)(createStore);
export default function configureStore(initialState) {
const store = createStoreWithMiddleware(
reducer,
initialState,
window.devToolsExtension && window.devToolsExtension()
);
if (module.hot) {
module.hot.accept('../reducers', () => {
const nextRootReducer = require('../reducers/index').default
store.replaceReducer(nextRootReducer);
});
}
return store;
}
Я действительноизвините за флуд с таким большим количеством кода, но я действительно не знаю, что здесь не так.