Rudx-thunk did a great job to dispatch async actions, it will eventually modify the state fetched in async action. But how do I know the moment when it finally modify the redux state fetched?
In my case, I want to read config from the server, because there are components need these config so I have to render the whole app after the config is fetched. But so far I cannot work out by using redux-thunk or any other redux async middlewares.
Update #1 show some code to express myself better.
// reducer
(state, action) => Object.assign({}, state, {config: action.config});
// action creator
const fetchConfig = () => (dispatch) => {
fetch('http://server.com/...')
.then(config=>dispatch({type: 'LOAD_CONFIG', config}))
}
// connect reducer to state
createStore({config: configReducer})
// render
import { render } from 'react-dom';
render (<App><News /></App>)
// some component consume state.config
@connect(state=>{config: state.config})
const News = props=>(
<div>
{(props.config === '...')? <div>...</div> : <div>...</div>}
</div>
)
The above looks good, however due to the action may take time and update the states after the component first render, so the component may display unexpected results. What I really want to do is (I just write down the render part, others should be the same):
// render
loadConfigFinished
.then(()=> render((<App><News /></App>)))
Or
// render
on('loadConfigFinished', ()=> render((<App><News /></App>)));
Probably, I should do the 2nd way, just afraid it is not redux-y.
Anyway, the above is just a example showing sometimes we do need to be notified when some action finally dispatch to the redux state.
Looking at your code, I gather your question is simply: When do I render a component that depends on data from the server, while waiting for that data, without passing undefined
into my component?
I would have a container component that connects to the config state, and conditionally renders the component that needs it, or a loading template:
const Container = props => {
if (props.config) {
return <ConfiguredComponent config={props.config} />
} else {
return <Loading />
}
}