Giter VIP home page Giter VIP logo

Comments (7)

mrwillis avatar mrwillis commented on May 14, 2024 2

@mattbrunetti Nice work. That looks pretty solid. Yes I think that would be really useful. I would be happy to help out with that. I feel like a lot of people are using apollo and redux together.

from next-redux-wrapper.

kirill-konshin avatar kirill-konshin commented on May 14, 2024 1

I haven't tested this lib with Apollo, but I surely will give it a shot. In the mean time, PR is welcome.

from next-redux-wrapper.

mrwillis avatar mrwillis commented on May 14, 2024 1

I added some notes here on how to use redux with apollo. As @mattbrunetti said, you are free to use redux inside the apollo container because of how withData is created. I gave an example in the README. If you want to additionally do some redux state initialization, see @mattbrunetti's comment :)

from next-redux-wrapper.

mattbrunetti avatar mattbrunetti commented on May 14, 2024

@mrwillis I think perhaps there is not much use for this package if you are using the withData HOC from Next's with-apollo-and-redux example...

As the comments say in the example...

    render () {
      return (
        // No need to use the Redux Provider
        // because Apollo sets up the store for us
        <ApolloProvider client={this.apollo} store={this.redux}>
          <ComposedComponent {...this.props} />
        </ApolloProvider>
      )
    }

Because of that, you can just use react-redux's connect HOC anywhere in your app (provided it's within a withData() component) and it works as expected, with hot reloading and everything.

If you want to work with the redux store (dispatch actions) in your getInitialProps functions, you just have to refactor withData.js a bit, to (a) pass the redux store as an argument to getInitialProps and (b) include the entire state in serverState (not just state.apollo.data). Here is my version of it...

import React from 'react'
import PropTypes from 'prop-types'
import { ApolloProvider, getDataFromTree } from 'react-apollo'
import Head from 'next/head'
import initApolloClient from './initApolloClient'
import initReduxStore from './initReduxStore'

// Gets the display name of a JSX component for dev tools
function getComponentDisplayName (Component) {
  return Component.displayName || Component.name || 'Unknown'
}

export default function withData (ComposedComponent) {
  return class WithData extends React.Component {
    static displayName = `WithData(${getComponentDisplayName(
      ComposedComponent
    )})`
    static propTypes = {
      serverState: PropTypes.object.isRequired,
    }

    static async getInitialProps (context) {
      let serverState = {}

      // Setup a one-time-use apollo client for initial props, and (server-side only) extracting serverState
      const apolloClient = initApolloClient()
      const reduxStore = initReduxStore({ apolloClient })

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

      // When redirecting, the response is finished.
      // No point in continuing to render
      if (context.res && context.res.finished) {
        return
      }

      // Run all GraphQL queries in the component tree and extract the resulting data
      if (!process.browser) {
        // Mimic the `url` prop that's used when rendering, but exclude the methods
        const url = { query: context.query, pathname: context.pathname }
        try {
          // Run all GraphQL queries
          await getDataFromTree(
            // No need to use the Redux Provider because Apollo sets up the store for us
            <ApolloProvider client={apolloClient} store={reduxStore}>
              <ComposedComponent url={url} {...composedInitialProps} />
            </ApolloProvider>
          )
        } catch (error) {
          // Prevent Apollo Client GraphQL errors from crashing SSR.
          // Handle them in components via the data.error prop:
          // http://dev.apollodata.com/react/api-queries.html#graphql-query-data-error
          // TODO: Log this
          console.error(error)
        }
        // getDataFromTree does not call componentWillUnmount
        // head side effect therefore need to be cleared manually
        Head.rewind()

        // Extract query data from the store
        serverState = reduxStore.getState()
      }

      return {
        serverState,
        ...composedInitialProps,
      }
    }

    constructor (props) {
      super(props)
      this.apolloClient = initApolloClient()
      this.reduxStore = initReduxStore({
        apolloClient: this.apolloClient,
        initialState: this.props.serverState,
      })
    }

    render () {
      return (
        // No need to use the Redux Provider because Apollo sets this up for us
        <ApolloProvider client={this.apolloClient} store={this.reduxStore}>
          <ComposedComponent {...this.props} />
        </ApolloProvider>
      )
    }
  }
}

Thinking about publishing this (with initApolloClient and initReduxStore) as a package next-apollo-redux-wrapper. What do you think?

from next-redux-wrapper.

j avatar j commented on May 14, 2024

@mrwillis just a side note, apollo is no longer going to have redux integrations baked in.

from next-redux-wrapper.

renato avatar renato commented on May 14, 2024

Confirming what @j said, Apollo now uses by default an in memory cache instead of the redux one, so I actually migrated from the withData in the next examples to this package so I could upgrade Apollo from 1.x to 2.x.

from next-redux-wrapper.

kirill-konshin avatar kirill-konshin commented on May 14, 2024

I have upgraded my Apollo project to 2.x, I can confirm that Redux wrapper is no longer needed for Apollo. Closing.

from next-redux-wrapper.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.