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

how to transfer values between redux and apollo-client ? #1964

Closed
jpabbuehl opened this issue May 14, 2017 · 10 comments
Closed

how to transfer values between redux and apollo-client ? #1964

jpabbuehl opened this issue May 14, 2017 · 10 comments

Comments

@jpabbuehl
Copy link

jpabbuehl commented May 14, 2017

Hi

looking at the example with-redux-and-apollo, I can't figure out how to copy a store's value to props such that it is passed to a child component performing a graphql query. Here's my current approach. I would greatly appreciate any hint, since using { connect } + MapStateToProps approach from 'react-redux' cannot access the store.

./lib/store.js

import Immutable from 'immutable'
const initialState = Immutable.fromJS({
    keyword: 'I want to query this sentence'
})
export default {
  search: (state = initialState, { type, payload }) => {
    switch (type) {
       default:
        return state
    }
}

./page/search.js

import SearchResult from '../containers/SearchResult'
import withData from '../lib/withData'
import App from '../components/App'

export default withData((props) => (
  <div>
    <App>
      <SearchResult keyword={'I DON'T KNOW HOW TO PASS REDUX-STATE HERE'}/>
		</App>
  </div>
))

./containers/SearchResult.js

import withData from '../lib/withData'
import { gql, graphql} from 'react-apollo';
import SearchResult from '../components/Search'

const search = gql`
  query search($keyword: String!, $size: Int!) {
    search(keyword: $keyword, size: $size){
      title
    }
}
`;

export default withData(graphql(search, {
  options: ({ keyword }) => ({
    variables: {
      keyword: { keyword },
      size: 10
    }
  }),
  props: ({ data }) => ({ data })
})(SearchResult))
@jpabbuehl jpabbuehl changed the title how to pass value from redux-immutable store to apollo how to transfer values between redux and apollo-client ? May 14, 2017
@tsupol
Copy link

tsupol commented May 15, 2017

@jpabbuehl I'd modify withData.js with

...await (Component.getInitialProps ? Component.getInitialProps({...ctx, store}) : {})

Notice that I added store to the parameters. Now in your search.js you can access Redux store to get the data like this.

static async getInitialProps ({ store, isServer }) {
    await store.dispatch(yourDesiredAction())

And to access the any Redux's state in your search.js page

export default withData(connect((state) => ({state}), mapDispatchToPropsIfYouWant)(SearchPage));

Not sure if this is the correct way but this works for me.

@timneutkens
Copy link
Member

@theednaffattack
Copy link

@tsupol
Thanks for your example. I tried the code below in /lib/withData.js with no joy. Any chance you have a handy repo I can peek at? I've been struggling with this for two days now and it's time to seek help from more senior devs.

static async getInitialProps (ctx, store) {
      let serverState = {}

      // Evaluate the composed component's getInitialProps()
      let composedInitialProps = {}
      if (ComposedComponent.getInitialProps) {
        composedInitialProps = await ComposedComponent.getInitialProps({...ctx, store})
      }
...

@timneutkens:
I'm trying to get the exact example you link to working and I still can't mapStateToProps successfully. I'm sure it's simple, but I'm definitely missing how. I can get my dispatches working by wrapping connect (that's react-redux 'connect', not apollo), along with mapDispatchToProps but not state.

The Apollo examples detailing how to wire Apollo and Redux together are great but it's been difficult to adapt them to work with handling the composed component (which is an awesome implementation) in withData.js

@tsupol
Copy link

tsupol commented Jul 12, 2017

@theednaffattack here is my quick code (not tested) that might help
Note: the rest are the same as @timneutkens's examples and you may have add your reducers and actions

import React from 'react'
// GQL
import { gql, graphql } from 'react-apollo'
// Redux
import { connect, compose } from 'react-redux'
import { bindActionCreators } from 'redux'
// Redux actions if needed
import { doReduxStuff } from '../../redux/filterActions'

class reactClass extends React.Component {

  constructor (props) {
    super(props)
  }

  onClick = (e) => {
    e.preventDefault()
    // dispatch a Redux action
    this.props.action.doReduxStuff({params: 'test'})
  }

  render () {
    // Note: no GQL code here for simplification
    return (
      <div>
        <h1>Data from Redux: {this.props.yourData}</h1>
        <button onClick={this.onClick}>Test Redux</button>
      </div>
    )
  }
}

// You may need to pay attention here
const reduxWrapper = connect(
  // I think this is what you are looking for
  state => ({
    yourData: state.yourData
  }),
  // You can also map dispatch to props
  dispatch => ({
    actions: {
      doReduxStuff: bindActionCreators(doReduxStuff, dispatch),
    }
  }))

// Apollo!
const query = gql`
  query users($id: Int!) {
    users(id: $id) {
      id
      name
    }
  }
`

const gqlWrapper = graphql(query, {
  options: (ownProps) => ({
    variables: {
      id: ownProps.id,
    }
  }),
})

// `compose` makes wrapping component much easier and cleaner
export default compose(
  reduxWrapper,
  gqlWrapper,
)(reactClass)

@theednaffattack
Copy link

@tsupol
You are the man (unless you are a woman, in which case you are supreme)!
I was actually just about to message that I'd found them (they were there under 'props.state'), but I really appreciate this example anyway as I don't know any devs getting into Apollo. Seeing how others approach this issue is a huge help to my personal development.

@jpabbuehl
Copy link
Author

@tsupol
Thank you very much, I ll give a try.
With the provided example, I was just able to use them both in parallel, without exchange.

@natterstefan
Copy link

@tsupol is this only working for react-apollo prior to their latest 2.0.x release or also for the latest one?

@ghost
Copy link

ghost commented Dec 5, 2017

@natterstefan I think it should work also with Apollo 2, but do you really need Redux?

@natterstefan
Copy link

@johnunclesam hello, actually the answer is no. 9 days ago I was not aware of how to use Apollo 2.0 properly, but not I have a much better picture in my head. Also thanks to these two (link1 and link2) links and the people who participated in each of them. thanks though for your comment.

@jmaylin
Copy link

jmaylin commented Jan 30, 2018

@tsupol Thanks!
Be careful though. compose is imported from redux, not from react-redux

@lock lock bot locked as resolved and limited conversation to collaborators Jan 30, 2019
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

6 participants