1.0.0 • Published 6 years ago
connect-initial-props v1.0.0
connect-initial-props
A decorator for Next.js and React-Redux apps to connect getInitialProps to state and dispatch.
Why?
When using react-redux on a Next.js project, the static getInitialProps method is executed before react-redux's had been able to map state and dispatch to props.
The result is that accessing the dispatching actions or later accessing the state in getInitialProps is complicated.
Using this decorator you will be able to access mapped state and dispatch actions just as you would access them in a non-static method.
Example
Without connect-initial-props:
static async getInitialProps(ctx) {
const { store, query, res } = ctx;
await store.dispatch(getItems({ page }));
const { totalPages } = mapStateToProps(store.getState());
if (page <= 1 || page > totalPages) {
res.redirect(301, '/?page=1');
return {};
}
return { page };
}With connect-initial-props's help:
@connectInitialProps(mapStateToProps, mapDispatchToProps)
static async getInitialProps(ctx, props) {
const { res } = ctx;
const { page, getItems } = props;
// async call to load items from api
await getItems({ page });
// props got updated with up-to-date state after async request
const { totalPages } = props;
if (page <= 1 || page > totalPages) {
res.redirect(301, '/?page=1');
return {};
}
}Full Component Example
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import connectInitialProps from 'connect-initial-props';
import { createStructuredSelector } from 'reselect';
import { selectItems, selectTotalPages } from './selectors';
import { getItems } from './slice';
const mapStateToProps = createStructuredSelector({
items: selectItems,
totalPages: selectTotalPages
});
const mapDispatchToProps = { getItems };
@connect(mapStateToProps, mapDispatchToProps)
class Example extends Component {
static propTypes = {
items: PropTypes.array.isRequired,
totalPages: PropTypes.number.isRequired
};+ @connectInitialProps(mapStateToProps, mapDispatchToProps)
- static async getInitialProps(ctx) {
+ static async getInitialProps(ctx, props) {
// We don't need store nor query anyore
- const { store, query, res } = ctx;
+ const { res } = ctx;
+ const { page, getItems } = props;
// No need to dispatch manually
- await store.dispatch(getItems({ page }));
+ await getItems({ page });
// No need provide store's state manually
- const { totalPages } = mapStateToProps(store.getState());
+ const { totalPages } = props;
if (page <= 1 || page > totalPages) {
res.redirect(301, '/?page=1');
return {};
}
} render() {
const { page, totalPages, items } = this.props;
return (
<>
<h1>
Page {page} of {totalPages}
</h1>
{items.map(item => (
<Item {...item} />
))}
</>
);
}
}