I've started learning React / Redux and stumbled on something that is probably a very basic question. Below are snippets from my app with some code removed for simplicity sake.
My state is described by an array of sites which is empty by default. Later reducer will have LOAD_SITES
action to load a different set of sites whenever user paginates to a different page but for now it's doing nothing. React starts by rendering PublishedSitesPage
which then renders PublishedSitesBox
which then loops over data and renders individual sites.
What I want to do is have it render everything with the default empty array and meanwhile initiate a "load sites from server" promise and once it resolves, dispatch LOAD_SITES
action. What is the best way to make this call? I was thinking about either constructor of PublishedSitesBox
or perhaps componentDidMount
. But not sure if this would work - my concern is that I'll create an endless loop this way that will keep re-rendering. I guess I could prevent this endless loop in some way by having some other state param along the lines of "haveRequestedInitialData". Another idea I had is to simply make this promise right after doing ReactDOM.render()
. What is the best and cleanest way to do this?
export default function sites(state = [], action) { switch (action.type) { default: return state; } } ... const publishedSitesPageReducer = combineReducers({ sites }); ReactDOM.render( <Provider store={createStore(publishedSitesPageReducer)}> <PublishedSitesPage /> </Provider>, this.$view.find('.js-published-sites-result-target')[0] ); ... export default function PublishedSitesPage() { return ( <PublishedSitesBox/> ); } ... function mapStateToProps(state) { return { sites: state.sites }; } const PublishedSitesBox = connect(mapStateToProps)(({sites}) => { // render sites });
Using the JavaScript Fetch API. The Fetch API through the fetch() method allows us to make an HTTP request to the backend. With this method, we can perform different types of operations using HTTP methods like the GET method to request data from an endpoint, POST to send data to an endpoint, and more.
The state in Redux is stored in memory. This means that, if you refresh the page the state gets wiped out. The state in redux is just a variable that persists in memory because it is referenced by all redux functions.
There's no reason for this data load logic to touch your React components at all. What you want here is for the return of the promise to dispatch an action to your reducers, which make the appropriate changes to the store, which then causes the React components to re-render as appropriate.
(It doesn't matter whether you kick off the async call before or after you call ReactDOM.render; the promise will work either way)
Something like this:
var store = createStore(publishedSitesPageReducer); someAsyncCall().then(function(response) { store.dispatch(someActionCreator(response)); }); ReactDOM.render( <Provider store={store}> <PublishedSitesPage /> </Provider>, this.$view.find('.js-published-sites-result-target')[0] );
Your React components are consumers of your store, but there's no rule that they need to be the ONLY consumers of your store.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With