The UI not update when hot-reload
njleonzhang opened this issue · 4 comments
enviroment:
"mobx": "^3.2.2",
"mobx-react": "^4.2.2",
"react": "^15.6.1",
"react-dom": "^15.6.1",
"react-router-dom": "^4.1.2",
"rfx-core": "^1.5.3"
entry:
.....
import "./stores" // init the store
const store = rehydrate()
ReactDOM.render(
<AppContainer>
<Router>
<Provider store={isProduction ? store : hotRehydrate()}>
<App />
</Provider>
</Router>
</AppContainer>,
document.getElementById('app'))
// hot reload config
if (module.hot) {
module.hot.accept(() => renderApp(App))
}
@withRouter // make react-router work
@inject('store')
@observer
export default class App extends Component {
constructor(props) {
super(props)
this.store = this.props.store.appState
}
componentDidMount() {
this.store.setDate('2017-11-11')
}
render() {
return (
<div className="App">
<div className="App-header">
<img src={img} className="App-logo" alt="logo" />
<h2>Welcome to React {this.store.dateStr}</h2>
</div>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload. {this.store.testVal}
</p>
..........
)
}
}
Store:
export default class AppState {
@observable testVal
constructor() {
this.testVal = '123'
}
}
import { store } from 'rfx-core'
import AppState from './AppState'
export default store.setup({
appState: AppState,
......
})
After updating Store
, for example, change this.testVal = '123'
to this.testVal = '1234'
, the log shows Store has changed, but the UI not updated.
Here is the sample project, would you please help to check?
https://github.com/njleonzhang/my-react-starter
fixed by myself
Please share your fix, can be useful for other users too
Sample project.
- for non rfx-core version: https://github.com/njleonzhang/my-react-starter
- for rfx-core version: https://github.com/njleonzhang/my-react-starter/tree/ssr-rfx-core
Points:
- In main.jsx, watch both
App
, andstore
module.hot.accept(['./components/App', './stores'], () => {
const newApp = require('./components/App').default
renderApp(newApp)
})
- in App.jsx, importing
store
to makestore
a child component ofApp.jsx
, so that when we change store code, theApp.jsx
can be triggered to run hot reload.
import '../../stores' // for hot-reload, make code change in store trigger App.jsx reload
rfx-core
keeps current value of store
when hot-reload. but when working with react-router
, the hot reload will also trigger router, so if you change store
in react hook componentDidMount
, then the store value you kept through rfx-core
will still be override by router
. So in this scenario, the benefit of rfx-core
(I mean keep state
) becomes useless.
At the same time, rfx-core
(keep state
) can cause another side-effect. For example, I have a testVal = 123
in store, and when I change it to testVal = 1234
, it seems the new value can not be updated to store. because the old value 123
is kept. (I am not sure if this is caused by my config)
I need react-router
, and most of the time, I change store when router change(get data from server), kept store value
is always override by router change
in my project. so I remove rfx-core
and use a normal store. this can work currently(not sure if will encounter other issues) with the next warning:
MobX Provider: Provided store 'store' has changed. Please avoid replacing stores as the change might not propagate to all children
So it seems there is no solution now to make hot-reload work perfect with mobx
+ react
+ react-router
+ mobx-react-router
. A perfect solution need to keep current value, update changed value, at the same time not be override by router
, hope react professional can make a solution. @foxhound87
Sorry for my poor english, hope can help or inspire someone.
Thanks for your effort!