Basic Usage
This guide uses the example page setup described on the start page of usage guide
Initializing a basic component
Below we will fetch links from an API to show in our <Footer>
component. This is a good place to start because that initialization task has no parameters. We need to do 2 things:
- Wrap
<Footer>
inwithInitAction()
- Prepare
<Footer>
on our parent page (<PostDetailPage>
)
1. Adding an init action to Footer
Our <Footer>
component has a react-redux
connect()
call to retrieve footer links from the store. Something like this:
// Footer.jsx
const mapStateToProps = state => ({
links: state.footer.links
});
export default connect(mapStateToProps)(Footer);
We have a fetchFooterLinks()
thunk action that returns a promise once our links are fetched from the API. Let’s add this action as an init action using withInitAction()
.
// Footer.jsx
import { withInitAction } from 'react-redux-component-init';
import { fetchFooterLinks } from './actions/apiActions';
// Update the export to:
export default withInitAction(
(props, dispatch) => dispatch(fetchFooterLinks()),
)(
connect(mapStateToProps)(Footer)
);
Optional: compose() higher order components
You might find the braces getting a bit messy when using multiple higher-order components like
withInitAction()
andconnect()
. One way to clean this up is by using the reduxcompose()
utility.// Footer.jsx import { compose } from 'redux';
const addInitAction = withInitAction( (props, dispatch) => dispatch(fetchFooterLinks()), ); const connector = connect(mapStateToProps); export default compose(withInitAction, connector)(Footer);
2. Preparing the Footer component on our page
Currently, react-redux-component-init
has no way of knowing that <Footer>
will be on your page before rendering with react. That means it did not call fetchFooterLinks()
. This is likely to cause serious issues in your application. That’s why when you render the page, it will immediately throw the following error:
Expected component “Footer” to be prepared but prepareComponent has not been called…
To fix this, we can prepare our components by dispatching prepareComponent()
. Remember from the setup instructions that prepareComponents()
is already dispatched for our top-level page component <PostDetailPage>
. We will now add withInitAction()
to our <PostDetailPage>
to make sure <Footer>
is also prepared.
// PostDetailPage.jsx
import { withInitAction, prepareComponent } from 'react-redux-component-init';
import Footer from './components/Footer';
// Update the export to:
export default withInitAction(
(props, dispatch) => dispatch(prepareComponent(Footer)),
)(PostDetailPage);
You only have to prepare components that are mounted on the initial page render by the server. Components that are mounted later by the browser do not need to be prepared.
Our <Footer>
is now fully setup! Let’s summarize what happens once we render the page:
- The server calls
prepareComponents()
on the top-level component<PostDetailPage>
<PostDetailPage>
has an init action that callsprepareComponent()
on our<Footer>
- The init action for
<Footer>
callsfetchFooterLinks()
. This will fetch data from the api and store it in the redux store - The server can now render the page using react
Let’s look at a more complex component next.