Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add documentation for using with an immutable redux store #30

Closed
rblakemesser opened this issue Mar 2, 2017 · 3 comments
Closed

Add documentation for using with an immutable redux store #30

rblakemesser opened this issue Mar 2, 2017 · 3 comments
Labels

Comments

@rblakemesser
Copy link

rblakemesser commented Mar 2, 2017

It took me a minute to get redux-query working with a redux-immutable store, so I thought I'd share. Apologies if this is the wrong venue.

Basically the lowest-surface area solution seemed to be to just wrap the provided redux-query reducers with some immutable serialization logic.

Define reducers/entities.js as:

import Immutable from 'immutable';
import { entitiesReducer } from 'redux-query';


// wrap the redux-query reducer immutable serialization logic
const wrappedEntitiesReducer = function(state = Immutable.Map(), action) {
	return Immutable.fromJS(entitiesReducer(state.toJS(), action));
};

export default wrappedEntitiesReducer;

Then reducers/queries.js as:

import Immutable from 'immutable';
import { queriesReducer } from 'redux-query';


// wrap the redux-query reducer immutable serialization logic
const wrappedQueriesReducer = function(state = Immutable.Map(), action) {
	return Immutable.fromJS(queriesReducer(state.toJS(), action));
};

export default wrappedQueriesReducer;

Then use your wrapped versions when you call combineReducers:

import { combineReducers } from 'redux-immutable';

import entities from 'reducers/entities';
import queries from 'reducers/queries';

const rootReducer = combineReducers({
	...etc,
	entities,
	queries
});

export default rootReducer;

And of course, the middleware selector functions in store.js:

const getQueries = state => state.get('queries');
const getEntities = state => state.get('entities');

It would be more efficient to have built-in immutable support, but absent that I was happy enough to just get it working.

@ryanashcraft
Copy link
Contributor

Thanks for sharing, @rblakemesser.

@acontreras89
Copy link
Contributor

@ryanashcraft I've been thinking about something since I started working with redux-query, which is described in the README as

a library for querying and managing network state in React/Redux applications.

If that's its scope, why does it impose its own entities reducer?

Don't take me wrong, I'm ok with redux-query shipping an entity reducer for whoever wants to make use of it, but I'd love to be able to opt it out in a simple manner.

For now, what I'm doing is something like this:

const mapDispatchToProps = { actionCreator }

const mapPropsToQuery = (props) => ({
  url: `api/todos`,
  // gets dispatched as soon as the requests completes
  transform: props.actionCreator,
  update: {} // required by redux-query
})

const enhance = compose(
  connect(void 0, mapDispatchToProps),
  connectRequest(mapPropsToQuery)
)

export default enhance(Component)

Note that I'm using trasnform instead of update to have a more generic code, but it would work either way. #2 uses a similar approach.

Where actionCreator is in charge of handling responses (normalize and store data, and potentially other stuff like handling pagination logic.) This enables me to work with my own reducers.

However, to roll back optimistic updates, I'd need to have my entities reducer react to the MUTATE_FAILURE action. #9 (which was created by the same user as #2) proposes adding other callbacks which could help in dealing with this scenario.

Even if this was added I feel like the code for updating entities (optimistically and otherwise) is too coupled to your implementation of the entities reducer. Both this issue and #34 display how cumbersome it can be to use your own reducers.

I'd love to hear your thoughts on this :)

@ryanashcraft
Copy link
Contributor

@acontreras89 FYI the rollback handler has been added in 2.0.

As far as it goes with the coupling between entities reducer and the middleware – I don't have a better answer other than redux-query is opinionated in this way. Having this coupling keeps the overall API simpler for our use case where we want all of the network state in a single location.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants