Comments (7)
@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.
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.
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.
@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.
@mrwillis just a side note, apollo is no longer going to have redux integrations baked in.
from next-redux-wrapper.
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.
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)
- No HYDRATE action dispatched
- client.js:1 Warning: Cannot update a component (`Home`) while rendering a different component (`App`). To locate the bad setState() call inside `App` HOT 5
- Meaning of the hydrating flag in the new version HOT 3
- Next 13 with next-redux-wrapper HOT 13
- Possible documentation bug.
- Internal Hooks are broken with Next 13 and React 18 HOT 4
- Two initialState passed to client when using _app.tsx + getServerSideProps HOT 1
- NextRouter was not mounted when using next-redux-wrapper HOT 7
- impact on performance when store rerenders on every request. HOT 1
- State value reset between page transitions in Next.js with Redux Toolkit and Next Redux Wrapper HOT 1
- parameter 'context' is empty for makeStore function
- Redux Toolkit example is unclear
- Breaking change from `[email protected]`: Error: `builder.addCase` cannot be called with an empty action type
- Redux Selector does not update when slice data is updated HOT 2
- GSSP ajax-mode -- HYDRATE-action not dispatching
- Types issue with 8.0.1 version of Next Redux Wrapper and Nextjs 13.4.19
- Strange Hydration action
- Typescript error when using object as parameter for makeStore function
- Wrapper doesn't support Next 14 HOT 4
- state getting empty before navigating to another SSR page.
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from next-redux-wrapper.