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

Redux: store state and reducers #384

Closed
Vanuan opened this issue Jul 11, 2016 · 11 comments
Closed

Redux: store state and reducers #384

Vanuan opened this issue Jul 11, 2016 · 11 comments
Milestone

Comments

@Vanuan
Copy link

Vanuan commented Jul 11, 2016

As far as I read, there's no way to pass a graphql response through reducers. I've looked into "apollo" state object but it doesn't seem to provide the same data we have in component's properties (in mapQueriesToProperties).

I'm new to redux, but should we be able to preprocess server's response before passing them on to React components?

I've tried dispatching data in React component but it doesn't feel right.

Is there a way to move data from queries to store?

@stubailo
Copy link
Contributor

I'd suggest not copying GraphQL state into a new part of the store unless you really need to. If you need to reformat arguments, you can easily just use a new intermediate component:

funcition MyComponentReformatted(props) {
  return <MyComponent myProp={prop.data.thing} />
}

@Vanuan
Copy link
Author

Vanuan commented Jul 12, 2016

What if need some computed fields? Putting that logic to a component doesn't feel right. I thought I should be using reducers. But in reducers I don't have access to GraphGL data. Do I?

@Vanuan
Copy link
Author

Vanuan commented Jul 12, 2016

Can I just handle APOLLO_QUERY_RESULT? Or is it a private action?

@abhiaiyer91
Copy link
Contributor

You can always use redux-thunk to fetch the data and put it in another reducer.
http://docs.apollostack.com/apollo-client/redux.html#async-actions

@jbinto
Copy link

jbinto commented Jul 12, 2016

This issue interests me.

We use a form library which is entirely stateless: it uses the onChange/value pattern and requires another component with local state (or a Redux store, etc) to manage its state.

Currently, we're using a Redux store with keys form and apollo.

We'd like to be able to extract data out of the Apollo query response, and populate the form state tree.

Right now, we're using components to deal with this, which feels a level or two too far down. Here's how we're managing to do it:

  • We have 3 components:
    • Component (props-driven, completely unaware of Apollo)
    • Container (props-driven, not connected to Apollo but aware of it, e.g. depends on structure of query props)
    • ContainerWithData (e.g. Container with Apollo connect(), not testable/storybook-able)

All of the following applies to Container:

  • We use mapQueriesToProps, and we extract the bit of the query result we're interested in via props.myQuery.foo.bar.baz. (This is the initial form state.)
  • We also use mapStateToProps, which plucks form.data out of the state tree, and passes it into Container's data prop. (This is the current form state.)
  • If props.data (from the Redux tree) is empty (the initial state from the reducer), we render Component using data={props.myQuery.foo.bar.baz} (initial)
  • If props.data (from the Redux tree) is not empty, we render Component using data={props.data} (current -- via mapStateToProps)

It would be nice if Container could rely on looking in just one place, that is: the form in the Redux store, so we could eliminate this conditional logic.

This would (might?) require some way to intercept query responses and place them in different parts of the redux tree.

It seems that this approach isn't really what react-apollo is designed for, though. Maybe (probably) I'm misunderstanding something.

@stubailo
Copy link
Contributor

Hmm, personally I would have actually used the approach that you just described. But I can understand that it's not appealing to everyone.

How about dispatching an action inside your componentDidMount to populate the form part of the store? You can do this by getting the data from mapQueriesToProps, or you can dispatch a thunk action like Abhi suggested above.

By the way, connect from Apollo actually passes in the query method as a prop of your component, so you can just call that if you need to fetch data at any time. I wouldn't rely on mapQueriesToProps handling every possible situation - sometimes you will need to query directly.

@helfer helfer added this to the New API/Refactor milestone Sep 29, 2016
@helfer
Copy link
Contributor

helfer commented Oct 26, 2016

You can now use the reducer option on watchQuery for this purpose (in theory). It's not exactly what they're intended for, but it should work. I would however suggest updating your GraphQL schema in such a way that this kind of data manipulation isn't necessary.

@helfer helfer closed this as completed Oct 26, 2016
@bojandragojevic
Copy link

bojandragojevic commented Nov 3, 2016

I have same question.

We know that is redux if you want to apply some additional logic on your data response in state before you pass it to component you can do it in selector. But since with apollo you connect data response directly to component I don't know where to apply this logic, here we do not have selectors.

so we know store can look like this if we use redux and apollo

const state = {
  redux: {// application state},
  apollo: {// apollo state and data}
}

So for redux you would select piece of state and pass it mapStateToProps and before you pass it you can apply some business logic to selected peace of state, but how to apply it to apollo peace of state?

@helfer
Copy link
Contributor

helfer commented Nov 4, 2016

I believe you can pass a props function to the graphql HOC in react-apollo to format the props. If that's not what you're looking for, I think you should ask the question on the react-apollo repo.

@bojandragojevic
Copy link

That is one way but I prefer to keep data manipulation in data layer not to do it in UI layer.

@n1ru4l
Copy link
Contributor

n1ru4l commented Jan 11, 2017

I also have the problem that I have a huge amount of data which should be transformed on the client only in order to render a svg graphic. I do not know where I would have to start since I want this all be handled on the data layer.

It got really messy be combining it with the components in Ember.js, so we are searching for a nice alternative and we are interested in using react, redux + apollo-client to solve these problems

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

No branches or pull requests

7 participants