Security News
NVD Backlog Tops 20,000 CVEs Awaiting Analysis as NIST Prepares System Updates
NVD’s backlog surpasses 20,000 CVEs as analysis slows and NIST announces new system updates to address ongoing delays.
next-redux-wrapper
Advanced tools
The next-redux-wrapper package is a utility that helps integrate Redux with Next.js applications. It simplifies the process of setting up Redux in a Next.js environment by providing a higher-order component (HOC) that can wrap the Next.js App component, ensuring that the Redux store is properly initialized and available throughout the application.
Store Initialization
This feature allows you to initialize a Redux store and wrap your Next.js application with it. The `createWrapper` function from next-redux-wrapper is used to create a wrapper that can be applied to the Next.js App component.
import { createStore } from 'redux';
import { createWrapper } from 'next-redux-wrapper';
const reducer = (state = { count: 0 }, action) => {
switch (action.type) {
case 'INCREMENT':
return { ...state, count: state.count + 1 };
default:
return state;
}
};
const makeStore = () => createStore(reducer);
export const wrapper = createWrapper(makeStore);
Server-Side Rendering (SSR) with Redux
This feature demonstrates how to use next-redux-wrapper to handle server-side rendering with Redux. The `getServerSideProps` function is wrapped with `wrapper.getServerSideProps`, allowing you to dispatch actions and access the Redux store on the server side.
import { wrapper } from '../store';
const Page = ({ count }) => (
<div>
<h1>Count: {count}</h1>
</div>
);
export const getServerSideProps = wrapper.getServerSideProps((store) => async () => {
store.dispatch({ type: 'INCREMENT' });
return { props: { count: store.getState().count } };
});
export default Page;
Static Site Generation (SSG) with Redux
This feature shows how to use next-redux-wrapper for static site generation with Redux. The `getStaticProps` function is wrapped with `wrapper.getStaticProps`, enabling you to dispatch actions and access the Redux store during the build process.
import { wrapper } from '../store';
const Page = ({ count }) => (
<div>
<h1>Count: {count}</h1>
</div>
);
export const getStaticProps = wrapper.getStaticProps((store) => async () => {
store.dispatch({ type: 'INCREMENT' });
return { props: { count: store.getState().count } };
});
export default Page;
The next-redux-saga package integrates Redux-Saga with Next.js. It provides a similar HOC to wrap the Next.js App component, but it focuses on managing side effects using Redux-Saga. Compared to next-redux-wrapper, it adds the capability to handle complex asynchronous flows with sagas.
The next-redux-cookie-wrapper package extends next-redux-wrapper by adding support for persisting Redux state in cookies. This is useful for maintaining state across server and client in a Next.js application. It offers similar functionality to next-redux-wrapper but with added state persistence capabilities.
npm install next-redux-wrapper --save
Wrapper has to be attached your page components (located in /pages
). For safety it is recommended
to wrap all pages, no matter if they use Redux or not, so that you should not care about it anymore in
all child components.
Here is the minimal setup (makeStore
and reducer
usually are located in other files):
import React, {Component} from "react";
import {createStore} from "redux";
import withRedux from "next-redux-wrapper";
const reducer = (state = {foo: ''}, action) => {
switch (action.type) {
case 'FOO':
return {...state, foo: action.payload};
default:
return state
}
};
/**
* @param {object} initialState
* @param {boolean} options.isServer indicates whether it is a server side or client side
* @param {Request} options.req NodeJS Request object (if any)
* @param {boolean} options.debug User-defined debug mode param
* @param {string} options.storeKey This key will be used to preserve store in global namespace for safe HMR
*/
const makeStore = (initialState, options) => {
return createStore(reducer, initialState);
};
class Page extends Component {
static getInitialProps({store, isServer, pathname, query}) {
store.dispatch({type: 'FOO', payload: 'foo'}); // component will be able to read from store's state when rendered
return {custom: 'custom'}; // you can pass some custom props to component from here
}
render() {
return (
<div>
<div>Prop from Redux {this.props.foo}</div>
<div>Prop from getInitialProps {this.props.custom}</div>
</div>
)
}
}
Page = withRedux(makeStore, (state) => ({foo: state.foo}))(Page);
export default Page;
No magic is involved, it auto-creates Redux store when getInitialProps
is called by Next.js and then passes this store
down to React Redux's Provider
, which is used to wrap the original component, also automatically. On the client side
it also takes care of using same store every time, whereas on server new store is created for each request.
The withRedux
function accepts makeStore
as first argument, all other arguments are internally passed to React
Redux's connect()
function for simplicity. The makeStore
function will receive initial state as one argument and
should return a new instance of redux store each time when called, no memoization needed here, it is automatically done
inside the wrapper.
withRedux
also optionally accepts an object. In this case only 1 parameter is passed which can contain the following
configuration properties:
createStore
(required, function) : the makerStore
function as described abovestoreKey
(optional, string) : the key used on window
to persist the store on the clientdebug
(optional, boolean) : enable debug loggingmapStateToProps
, mapDispatchToProps
, mergeProps
(optional, functions) : functions to pass to react-redux
connect
methodconnectOptions
(optional, object) : configuration to pass to react-redux
connect
methodWhen makeStore
is invoked it is also provided a configuration object as the second parameter, which includes:
isServer
(boolean): true
if called while on the server rather than the clientreq
(Request): The next.js
getInitialProps
context req
parameterquery
(object): The next.js
getInitialProps
context query
parameterThe object also includes all configuration as passed to withRedux
if called with an object of configuration properties.
Use withRedux
to wrap only top level pages! All other components should keep using regular connect
function of
React Redux.
Although it is possible to create server or client specific logic in both createStore
function and getInitialProps
method I highly don't recommend to have different behavior. This may cause errors and checksum mismatches which in turn
will ruin the whole purpose of server rendering.
I don't recommend to use withRedux
in both top level pages and _document.js
files, Next.JS
does not have provide a reliable way to determine the sequence when
components will be rendered. So per Next.JS recommendation it is better to have just data-agnostic things in _document
and wrap top level pages with another HOC that will use withRedux
.
getInitialProps
function someAsyncAction() {
return {
type: 'FOO',
payload: new Promise((res) => { res('foo'); })
}
}
function getInitialProps({store, isServer, pathname, query}) {
// lets create an action using creator
const action = someAsyncAction();
// now the action has to be dispatched
store.dispatch(action);
// once the payload is available we can resume and render the app
return action.payload.then((payload) => {
// you can do something with payload now
return {custom: 'custom'};
});
}
If you want to use Immutable.JS then you have to modify your makeStore
function, it should detect if object is an instance of Immutable.JS, and if not - convert it using Immutable.fromJS
:
export default function makeStore(initialState = {}) {
// Nasty duck typing, you should find a better way to detect
if (!!initialState.toJS) initialState = Immutable.fromJS(initialState);
return createStore(reducer, initialState, applyMiddleware(thunk));
}
The reason is that initialState
is transferred over the network from server to client as a plain object (it is automatically serialized on server) so it should be converted back to Immutable.JS on client side.
Here you can find better ways to detect if an object is Immutable.JS: https://stackoverflow.com/a/31919454/5125659.
npm install @types/next-redux-wrapper
FAQs
Redux wrapper for Next.js
The npm package next-redux-wrapper receives a total of 105,098 weekly downloads. As such, next-redux-wrapper popularity was classified as popular.
We found that next-redux-wrapper demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
NVD’s backlog surpasses 20,000 CVEs as analysis slows and NIST announces new system updates to address ongoing delays.
Security News
Research
A malicious npm package disguised as a WhatsApp client is exploiting authentication flows with a remote kill switch to exfiltrate data and destroy files.
Security News
PyPI now supports digital attestations, enhancing security and trust by allowing package maintainers to verify the authenticity of Python packages.