Skip to content

Add apollo example with next.js #733

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

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions examples/apollo-redux-next/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.idea
.next
node_modules
.DS_Store
33 changes: 33 additions & 0 deletions examples/apollo-redux-next/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

# Redux example

## How to use

This boilerplate was continued from [zeit official example](https://github.com/zeit/next.js/tree/master/examples/with-redux).

To use this boilerplate, first clone or download this repo: [https://github.com/SkyRocketDevelopment/nextjs-apollo-redux-boilerplate.git].

```bash
git clone https://github.com/SkyRocketDevelopment/nextjs-apollo-redux-boilerplate.git *your-project-name*
```

cd into it and run:

```bash
npm install
npm run dev
```

Or use `yarn` to install dependencies (recommended).

Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download))

```bash
now
```

### Live example:

[https://nextjs-redux-boilerplate-unqassuzej.now.sh]

Live example uses our FoodTruck App GraphQl [https://www.elfoodtruckr.com/graphiql]!
12 changes: 12 additions & 0 deletions examples/apollo-redux-next/actions/demoActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const SET_STRING = 'SET_STRING'
/**
* sets the string, if none is passed, it will default to the below string.
* @param theString
* @return {{type: string, theString: String}}
*/
export function setString (theString: String = 'the default string') {
return {
type: SET_STRING,
theString
}
}
12 changes: 12 additions & 0 deletions examples/apollo-redux-next/actions/kittensActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const SET_KITTENS = 'SET_KITTENS'
/**
* Set the kittens(data response) from parameter to redux state.
* @param kittens
* @return {{type: string, kittens: Object}}
*/
export function setKittens (kittens: Object) {
return {
type: SET_KITTENS,
kittens
}
}
13 changes: 13 additions & 0 deletions examples/apollo-redux-next/api/kittens/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import axios from 'axios'
/**
* Get the response of the api call to get the kitten list.
* If you want to create your api check this repository https://github.com/jsantana90/nextjs-express-boilerplate
* @return {AxiosPromise}
*/
function getKittens () {
return axios.get('https://nextjs-express-boilerplate-vxqbpvxtnf.now.sh/')
}

export {
getKittens
}
35 changes: 35 additions & 0 deletions examples/apollo-redux-next/components/layout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React, { Component, PropTypes } from 'react'
import Link from 'next/link'
import Head from 'next/head'

class Layout extends Component {
static propTypes = {
title: PropTypes.string
};
render () {
const { title, children } = this.props
return (
<div>
<Head>
<title>{ title }</title>
<meta charSet='utf-8' />
<meta name='viewport' content='initial-scale=1.0, width=device-width' />
</Head>
<header>
<nav>
<Link href='/'> Home </Link> |
<Link href='/about'> About </Link>
</nav>
</header>

{ children }

<footer>
This is the footer
</footer>
</div>
)
}
}

export default Layout
72 changes: 72 additions & 0 deletions examples/apollo-redux-next/containers/about.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import React, { Component, PropTypes } from 'react'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import Layout from '../components/layout'
import { getKittens } from '../api/kittens'
import * as kittensActions from '../actions/kittensActions'
/**
* About component to show a list of kittens fetched from an external api.
* Express api boilerplate with nextJS https://github.com/jsantana90/nextjs-express-boilerplate
*/
class About extends Component {
static propTypes = {
/**
* an object response from api call, this is set from redux action.
*/
kittens: PropTypes.object.isRequired,
/**
* A redux function to set the kittens fetched from the api.
*/
setKittens: PropTypes.func.isRequired
};

componentDidMount () {
const { setKittens } = this.props
console.log('properties: ', this.props)
getKittens().then(function (response) {
console.log(response)
setKittens(response)
})
.catch(function (error) {
console.log(error)
})
}
render () {
const { kittens } = this.props
return (
<Layout title='About us'>
{
kittens.data
? <div>
<h2>About us</h2>
<p>We are kittens: </p>
<ul>
{
kittens.data.map((cat, index) => {
return (
<li key={index}>
{cat.name}
</li>
)
})
}
</ul>
</div>
: <p>Loading</p>
}
</Layout>
)
}
}

function mapStateToProps (state) {
return {
kittens: state.kittens
}
}

function mapDispatchToProps (dispatch) {
return bindActionCreators(kittensActions, dispatch)
}

export default connect(mapStateToProps, mapDispatchToProps)(About)
82 changes: 82 additions & 0 deletions examples/apollo-redux-next/containers/home.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import React, { Component, PropTypes } from 'react'
import { connect } from 'react-redux'
import { graphql } from 'react-apollo'
import gql from 'graphql-tag'
import { bindActionCreators } from 'redux'
import Layout from '../components/layout'
import * as demoActions from '../actions/demoActions'
/**
* Home component to show basic redux usage with nextjs.
*/
class Home extends Component {
static propTypes = {
/**
* demo string from redux actions.
*/
demoString: PropTypes.string.isRequired,
/**
* redux function from actions to set the string, accepts a string param,
* if none is passed, it will return the default string set in the action.
*/
setString: PropTypes.func.isRequired
};
constructor () {
super()
this.changeDemoString = this.changeDemoString.bind(this)
}
componentDidMount () {
const { setString } = this.props
setString()
}
/**
* Change the demo string to whatever you pass as a parameter.
* @param {string} theString - String to be passed to show in component.
*/
changeDemoString (theString: String) {
const { setString } = this.props
setString(theString)
}

render () {
const { demoString } = this.props
const { foodtrucks, loading } = this.props.data
return (
<Layout title='Home page'>
<button
onClick={() => this.changeDemoString('not the default string')}
>
change demo string of redux store property to 'not the default string'
</button>
<button
onClick={() => this.changeDemoString()}
>
change back to default
</button>
{
loading ? <p> Loading ...</p>
: <p> Found { foodtrucks.length} foodtrucks!</p>
}
<p>{demoString}</p>
</Layout>
)
}
}

function mapStateToProps (state) {
return {
demoString: state.demoString
}
}

function mapDispatchToProps (dispatch) {
return bindActionCreators(demoActions, dispatch)
}

const MyQuery = gql`query foodTrucks {
foodtrucks {
_id
name
}
}`
const HomeWithGraphQl = graphql(MyQuery)(Home)
export default connect(mapStateToProps, mapDispatchToProps)(HomeWithGraphQl)
21 changes: 21 additions & 0 deletions examples/apollo-redux-next/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "nextjs-redux-boilerplate",
"version": "1.0.0",
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
},
"dependencies": {
"apollo-client": "^0.7.1",
"axios": "^0.15.3",
"next": "^2.0.0-beta",
"react": "^15.4.2",
"react-apollo": "^0.8.1",
"react-redux": "^5.0.1",
"redux": "^3.6.0",
"redux-thunk": "^2.1.0"
},
"author": "",
"license": "ISC"
}
27 changes: 27 additions & 0 deletions examples/apollo-redux-next/pages/about.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react'
import { Provider } from 'react-redux'
import { initStore } from '../store'
import About from '../containers/about'
/**
* Component to show the about component.
*/
export default class App extends React.Component {
static getInitialProps ({ req }) {
const isServer = !!req
const store = initStore({}, isServer)
return { initialState: store.getState(), isServer }
}

constructor (props) {
super(props)
this.store = initStore(props.initialState, props.isServer)
}

render () {
return (
<Provider store={this.store}>
<About />
</Provider>
)
}
}
36 changes: 36 additions & 0 deletions examples/apollo-redux-next/pages/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react'
import ApolloClient, { createNetworkInterface } from 'apollo-client'
import { ApolloProvider } from 'react-apollo'
import { Provider } from 'react-redux'
import { initStore } from '../store'
import Home from '../containers/home'

const client = new ApolloClient({
networkInterface: createNetworkInterface({ uri: 'https://foodtruckserver.now.sh/graphql' })
})

/**
* Component to show the home container.
*/
export default class App extends React.Component {
static getInitialProps ({ req }) {
const isServer = !!req
const store = initStore({}, isServer)
return { initialState: store.getState(), isServer }
}

constructor (props) {
super(props)
this.store = initStore(props.initialState, props.isServer)
}

render () {
return (
<ApolloProvider client={client}>
<Provider store={this.store}>
<Home />
</Provider>
</ApolloProvider>
)
}
}
10 changes: 10 additions & 0 deletions examples/apollo-redux-next/reducers/demoReducer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { SET_STRING } from '../actions/demoActions'

export default function settingString (state: String = '', action: Object) {
switch (action.type) {
case SET_STRING:
return action.theString
default:
return state
}
}
8 changes: 8 additions & 0 deletions examples/apollo-redux-next/reducers/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { combineReducers } from 'redux'
import demoString from './demoReducer'
import kittens from './kittensReducer'

export default combineReducers({
demoString,
kittens
})
10 changes: 10 additions & 0 deletions examples/apollo-redux-next/reducers/kittensReducer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { SET_KITTENS } from '../actions/kittensActions'

export default function settingKittens (state: Object = {}, action: Object) {
switch (action.type) {
case SET_KITTENS:
return Object.assign({}, ...state, action.kittens)
default:
return state
}
}
Loading