# @gasket/redux Redux configuration for Gasket apps. ⚠️ _DEPRECATED - This package will be removed in a future major version._ ## Installation ``` npm i @gasket/redux ``` ## Functions ### configureMakeStore Set up Redux store configuration and return a `makeStore` function **Signature** - `configureMakeStore(options, [postCreate]): makeStore` - `configureMakeStore(optionsFn, [postCreate]): makeStore` **Props** - `options` - (object) Options object - `initialState` - (object) Optionally set any preloaded state - `reducers` - (object) Map of identifiers and reducer functions which will be [combined]. - `rootReducer` - (function) Optional entry reducer. If returned state is unchanged, it will pass through to combined `reducers`. - `middleware` - (function[]) Additional redux middleware to apply - `enhancers` - (function[]) Any other redux store enhancers - `logging` - (boolean) set to true if you want to enable redux logger. (default: false) - `optionsFn` - (function) function that returns the options object. - `postCreate` - (function) Executed after the store is create the resulting store as the argument **Return Value** - `makeStore` - (function) Creates the redux store for each server-side request and once on the client, hydrating with the state from the server. ### getOrCreateStore Creates a helper to check if an existing store is in the context, otherwise it will make a new instance. Context can include a `store` property directly or on `req` and can be Next.js App or Page context. **Signature** - `getOrCreateStore(makeStore): (context) => Store` **Props** - `makeStore` - (function) Creates the redux store for each server-side request and once on the client, hydrating with the state from the server. Will only be called if an existing store is not found within the context. ## Usage This package is only compatible with Gasket apps that use the [pages router] in Next.js with a [custom server]. Gasket apps no longer ship with a default redux configuration which includes the redux-thunk middleware. The `configureMakeStore` can be used to do any configuration. The most common use case is to add reducers at the app level. By default, custom store configurations can be placed in a `store.js` at the root of your app or in a `./redux` dir. If you wish for it to reside elsewhere, direct the `redux.makeStore` property to it in your app's `gasket.js` file. #### Example: adding reducers ```js // ./store.js import { configureMakeStore } from '@gasket/redux'; import reducers from './reducers'; // apps reducers export default configureMakeStore({ reducers }); ``` #### Example: initial state If you are adding keys to the initial state without reducers, you may get an `unexpected key found in previous state` error. In this case, consider using [@gasket/data] for these static-like values, or register placeholder reducers in your store. ```diff // ./store.js import { configureMakeStore } from '@gasket/redux'; import myReducers './reducers'; // apps reducers const reducers = { ...myReducers, + custom: f => f || null }; const initialState = { custom: 'example' }; export default configureMakeStore({ initialState, reducers }); ``` #### Example: adding middleware in a custom path (redux-saga) ```js // ./lib/make-store.js import sagaMiddleWare from 'redux-saga'.default(); import { configureMakeStore } from '@gasket/redux'; import reducers from '../reducers'; import rootSaga from '../sagas'; const middleware = [sagaMiddleWare]; export default configureMakeStore({ reducers, middleware }, store => { // The method below is only needed if you are utilizing // next-redux-saga wrapper for handling sagas in `getInitialProps` // store.runSagaTask = (saga) => { // store.sagaTask = sagaMiddleWare.run(saga); // }; // store.runSagaTask(rootSaga); // This is needed to initialize sagas store.sagaTask = sagaMiddleWare.run(saga); }); ``` Next in the gasket.js, set the `redux.makeStore` field to the file. This will start up the app using the custom configuration. ```js // gasket.js export default makeGasket({ redux: { makeStore: './lib/make-store.js' } }); ``` #### Example: passing custom thunk middleware The default thunk middleware can be overridden with a customized version by passing `thunkMiddleware`. A common use case for this is to use the `withExtraArgument` feature of `redux-thunk`. ```js // ./store.js import { configureMakeStore } from '@gasket/redux'; import reducers from './reducers'; import thunk from 'redux-thunk'; const myExtraArg = {}; const thunkMiddleware = thunk.withExtraArgument(myExtraArg); export default configureMakeStore({ reducers, thunkMiddleware }); ``` ## License [MIT](./LICENSE.md) [pages router]:https://nextjs.org/docs/pages [custom server]:https://nextjs.org/docs/pages/ [combined]: https://redux.js.org/api/combinereducers [@gasket/data]: /packages/gasket-data/README.md