Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I store function references in Redux store?

Tags:

redux

I'm trying to build keyboard shortcut support into my React/Redux app in an idiomatic React/Redux way. The way I am planning to do this is to have the following action creator and associated action:

registerShortcut(keyCode, actionCreatorFuncReference) 

The reducer would then update a registeredShortcuts object in the redux store with a mapping of keyCodes to actionCreatorFuncReferences. Then my root component would listen for keyup and see if there is an associated keyCode registered and if so, then dispatch the mapped action via the action creator function reference.

However, this would be the first time I am storing function references in my Redux store. To date, I've only had objects with keys with vanilla values (strings, ints, etc).

The Redux docs says:

You should do your best to keep the state serializable. Don’t put anything inside it that you can’t easily turn into JSON.

Does this suggest it's a bad idea to store such function references in my Redux store? If so, what is a better way to accomplish what I'm trying to do in React/Redux?

An alternative approach is just to store the mapping of keyCodes and function references in the root react component itself, but that didn't feel very Redux-like since now the application state is not in the Redux store.

like image 980
Sachin Rekhi Avatar asked Feb 10 '16 20:02

Sachin Rekhi


People also ask

What should you store in Redux store?

As an app gets large and complex, you might want to store large, bulky data inside your Redux store and access it inside a component. A Redux store doesn't have a limit on the amount of data stored, so you can pretty much use it to store almost anything, including bulky JSON data, data in table form, etc.

Can you store a ref in Redux?

You can keep them in your app's redux store in any persistence like web storage.

Should everything be stored in Redux?

Some users prefer to keep every single piece of data in Redux, to maintain a fully serializable and controlled version of their application at all times. Others prefer to keep non-critical or UI state, such as “is this dropdown currently open”, inside a component's internal state. Using local component state is fine.

Should I store form data in Redux?

We specifically recommend that most form state probably shouldn't be kept in Redux. However, it's your app, so you should evaluate the specific use cases you need to deal with to determine the right approach.


2 Answers

No, you should not store function references in the redux store. They are not serializable, and as you mentioned state should be serializable at all times. The most redux-friendly approach I can think of is just to keep the map of hotkeys to their actionCreatorFuncNames.

like image 122
Nathan Hagen Avatar answered Oct 02 '22 23:10

Nathan Hagen


You don't. The store state must be serializable at all times (as Nathan answered). The Redux way is via enhancers, or the Redux-Observable way via dependencies.

Based on the Redux docs example, what you want is to pass the reference in your action (1), ignore it in your reducer (2) and use it in your enhancer (3):

//... in your action: const data={val:1}, ref=()=>{}; const action = {type:'ACTION_WITH_REF', data, ref}; //(1)  //... in your reducer:    case 'ACTION_WITH_REF':    return {...state, data: action.data}; //(2)  //... and in your enhancer: import { createStore, applyMiddleware } from 'redux'; import reducers from './reducers'; export const myRefStore= {};   function refHandler({ getState }) {   return next => action => {     switch(action.type){         // this can be done more elegantly with a redux-observable        case 'ACTION_WITH_REF':          myRefStore.aRef = action.ref; // (3)          break;      }     // be sure to maintain the chain of the store     const returnValue = next(action);        // otherwise, your midddeware will break the store     return returnValue;   }; }   const store = createStore(   reducers,   initialState,   applyMiddleware(refHandler) ); 

Note: As far as there are no side effects in your enhancers, you are good to go. Be aware that you could have obtained the refs directly in the reducers, but such an approach keeps the reference at the reducer level and misses the point of combineReducers(). With an enhancer, you keep them all in one place(myRefStore).

One final observation is that a redux store is not an any-data store but a state store, thus why we need to handle functions and other non-state-related stuff in enhancers. You can leverage the enhancer backbone to Redux-Observable and inject myRefStore via dependencies.

like image 37
David I. Samudio Avatar answered Oct 03 '22 00:10

David I. Samudio