Skip to content

Commit

Permalink
add uniform wrapPageElement and wrapRootElement apis to SSR and Brows…
Browse files Browse the repository at this point in the history
…er (gatsbyjs#7204)

* Remove not used API hook

* save browser plugin names in development to identify plugins

* update using-redux example

* allow ssr and browser api runners to use return of previous plugin as input for another

* allow chaining of browser wrapRootComponent api

* add chainable wrapRootComponent api to ssr

* api docs corrections

* add wrapPageComponent to both ssr and browser APIs

* update replaceRouterComponent migration section

* add migration guide section on wrapRootComponent signature change

* add example to wrapPageComponent / wrapRootComponent

* add link to migration guide in console error

* update gatsby-plugin-jss

* styletron plugin and example update

* add gatsby-plugin-layout

* update styled-components plugin

* add using-multiple-providers-example

* fix lint

* add some clarification to docs

* gatsby-plugin-layout version sanity check + readme update

* let preferDefault do its jon - thanks porfirioribeiro

* rename wrapXcomponent to wrapXelement

* update migration guide

* migration guide docs update

* add console warning when wrapRootComponent is used with link to migration guide

* [gatsby-plugin-layout] default to `src/layouts/index.js`

* update gatsby-plugin-layout readme with default settings

* [gatsby-plugin-layout] proper version syntax

* use shortlink

* no need for plugin name, in browser requires list - migration check is done in node env now

* typos

* migration guide section rename

* link to gatsby-plugin-layout in layout component removal section

* missed typo
  • Loading branch information
pieh authored and m-allanson committed Aug 16, 2018
1 parent e6d54ba commit 8029c66
Show file tree
Hide file tree
Showing 46 changed files with 774 additions and 203 deletions.
46 changes: 44 additions & 2 deletions docs/docs/migrating-from-v1-to-v2.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ This is a reference for upgrading your site from Gatsby v1 to Gatsby v2. While t
- [APIs onPreRouteUpdate and onRouteUpdate no longer called with the route update action](#apis-onprerouteupdate-and-onrouteupdate-no-longer-called-with-the-route-update-action)
- [Browser API `replaceRouterComponent` was removed](#browser-api-replaceroutercomponent-was-removed)
- [Browser API `replaceHistory` was removed](#browser-api-replacehistory-was-removed)
- [Browser API `wrapRootComponent` was replaced with `wrapRootElement`](#browser-api-wraprootcomponent-was-replaced-with-wraprootelement)
- [Don't query nodes by ID](#dont-query-nodes-by-id)
- [Use Query in place of RootQueryType](#use-query-in-place-of-rootquerytype)
- [Typography.js Plugin Config](#typographyjs-plugin-config-changes)
Expand Down Expand Up @@ -122,7 +123,8 @@ In Gatsby v2, the special layout component (`src/layouts/index.js`) that wrapped
There are a number of implications to this change:

- To render different layouts for different pages, just use the standard React inheritance model. Gatsby no longer maintains, or needs to maintain, separate behavior for handling layouts.
- Because the "top level component" changes between each page, React will rerender all children. This means that shared components previously in a Gatsby v1 layout-- like navigations-- will unmount and remount. This will break CSS transitions or React state within those shared components. For more information, including in-progress workarounds, [see this ongoing discussion](https://github.com/gatsbyjs/gatsby/issues/6127).
- Because the "top level component" changes between each page, React will rerender all children. This means that shared components previously in a Gatsby v1 layout-- like navigations-- will unmount and remount. This will break CSS transitions or React state within those shared components. If your use case requires layout component to not unmount use [`gatsby-plugin-layout`](https://www.gatsbyjs.org/packages/gatsby-plugin-layout/).

- To learn more about the original decisions behind this removal, read the [RFC for removing the special layout component](https://github.com/gatsbyjs/rfcs/blob/master/text/0002-remove-special-layout-components.md).

The following migration path is recommended:
Expand Down Expand Up @@ -542,7 +544,27 @@ React Router allowed you to swap out its history object. To enable this in Gatsb
We did, erroneously, suggest using this API for adding support for Redux, etc. where you need to wrap the root Gatsby component with your own component.
If you were using `replaceRouterComponent` for this, you'll need to migrate to
`wrapRootComponent`. See this PR migrating the `using-redux` example site as a pattern to follow https://github.com/gatsbyjs/gatsby/pull/6986
`wrapRootElement`:

```diff
import React from 'react'
import { Provider } from 'react-redux'
-import { Router } from 'react-router-dom'
-export const replaceRouterComponent = ({ history }) => {
+export const wrapRootElement = ({ element }) => {
- const ConnectedRouterWrapper = ({ children }) => (
+ const ConnectedRootElement = (
<Provider store={store}>
- <Router history={history}>{children}</Router>
+ {element}
</Provider>
)
- return ConnectedRouterWrapper
+ return ConnectedRootElement
}
```

### Browser API `replaceHistory` was removed

Expand Down Expand Up @@ -874,6 +896,26 @@ Import graphql types from `gatsby/graphql` to prevent `Schema must contain uniqu
+const { GraphQLString } = require(`gatsby/graphql`)
```

### Browser API `wrapRootComponent` was replaced with `wrapRootElement`

Use new [`wrapRootElement`](/docs/browser-apis/#wrapRootComponent) API:
We now pass `component` Element instead of `Root` Component and expect that `wrapRootElement` will return Element and not Component. This change was needed to keep all wrapping APIs uniform.

```diff
-export const wrapRootComponent = ({ Root }) => {
+export const wrapRootElement = ({ element }) => {
- const ConnectedRootComponent = () => (
+ const ConnectedRootElement = (
<Provider store={store}>
- <Root />
+ {element}
</Provider>
)
- return ConnectedRootComponent
+ return ConnectedRootElement
}
```

## For Explorers

### Starting a New Project with v2
Expand Down
11 changes: 11 additions & 0 deletions examples/using-multiple-providers/gatsby-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module.exports = {
siteMetadata: {
title: `Gatsby with multiple providers`,
},
plugins: [
`gatsby-plugin-jss`,
`gatsby-plugin-styled-components`,
`gatsby-plugin-redux`,
`gatsby-plugin-apollo-client`,
],
}
32 changes: 32 additions & 0 deletions examples/using-multiple-providers/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"name": "gatsby-example-using-multiple-providers",
"private": true,
"description": "Gatsby example site using multiple plugins implementing wrapping APIs",
"version": "1.0.0",
"author": "Michal Piechowiak <[email protected]>",
"dependencies": {
"apollo-boost": "^0.1.13",
"babel-plugin-styled-components": "^1.5.1",
"gatsby": "next",
"gatsby-plugin-jss": "next",
"gatsby-plugin-styled-components": "next",
"isomorphic-fetch": "^2.2.1",
"react": "^16.4.0",
"react-apollo": "^2.1.11",
"react-dom": "^16.4.0",
"react-jss": "^8.6.1",
"react-redux": "^5.0.7",
"redux": "^4.0.0",
"styled-components": "^3.4.2"
},
"keywords": [
"gatsby"
],
"license": "MIT",
"main": "n/a",
"scripts": {
"develop": "gatsby develop",
"build": "gatsby build",
"serve": "gatsby serve"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const preferDefault = m => (m && m.default) || m
exports.wrapRootElement = preferDefault(require(`./inject-provider`))
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
require(`isomorphic-fetch`)

const preferDefault = m => (m && m.default) || m
exports.wrapRootElement = preferDefault(require(`./inject-provider`))
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from "react"
import ApolloClient from "apollo-boost"
import { ApolloProvider } from "react-apollo"

const client = new ApolloClient({
uri: `https://api-euwest.graphcms.com/v1/cjjr1at6d0xb801c3scjrm0l0/master`,
})

// eslint-disable-next-line react/prop-types,react/display-name
export default ({ element }) => (
<ApolloProvider client={client}>{element}</ApolloProvider>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
exports.wrapRootElement = require(`./inject-provider`)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
exports.wrapRootElement = require(`./inject-provider`)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const React = require(`react`)
const { Provider } = require(`react-redux`)
const { createStore } = require(`redux`)

const reducer = (state, action) => {
if (action.type === `SET_BLOG_POST`) {
return action.payload
}
return state
}

const initialState = { id: null, title: `None` }
const store = createStore(reducer, initialState)

// eslint-disable-next-line react/prop-types,react/display-name
module.exports = ({ element }) => <Provider store={store}>{element}</Provider>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
112 changes: 112 additions & 0 deletions examples/using-multiple-providers/src/pages/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import React from "react"
import { connect } from "react-redux"
import styled from "styled-components"
import { gql } from "apollo-boost"
import { Query } from "react-apollo"
import injectSheet from "react-jss"

const styles = {
listItem: {
cursor: `pointer`,
fontSize: `1.5em`,
color: `blue`,
textDecoration: `underline`,
},
}

const Counter = styled.p`
color: palevioletred;
`

const GET_POSTS = gql`
query {
blogPosts {
id
title
}
}
`

const GET_POST = gql`
query($id: ID) {
blogPost(where: { id: $id }) {
title
post
}
}
`

class IndexPage extends React.Component {
render() {
return (
<div>
<h1>Multiple provider-example</h1>
<h2>Redux component:</h2>
<Counter>
ReduxState:
<pre>{JSON.stringify(this.props.reduxState)}</pre>
</Counter>
<h2>Apollo</h2>
<h3>List (click on something)</h3>
<Query query={GET_POSTS}>
{({ loading, error, data }) => {
if (loading) return <div>Loading...</div>
if (error) return <div>Error :(</div>

return (
<ul>
{data.blogPosts.map(data => {
const { id, title } = data
return (
<li
className={this.props.classes.listItem}
onClick={() => {
this.props.setBlogPost(data)
}}
key={id}
>
{title}
</li>
)
})}
</ul>
)
}}
</Query>
{this.props.reduxState.id && (
<Query query={GET_POST} variables={{ id: this.props.reduxState.id }}>
{({ loading, error, data }) => {
if (loading) return <div>Loading...</div>
if (error) return <div>Error :(</div>

return (
<>
<h3>Details {data.blogPost.title}</h3>
<div>{data.blogPost.post}</div>
</>
)
}}
</Query>
)}
</div>
)
}
}

const mapStateToProps = state => {
return { reduxState: state }
}

const mapDispatchToProps = dispatch => {
return {
setBlogPost: blogPost =>
dispatch({ type: `SET_BLOG_POST`, payload: blogPost }),
}
}

const ReduxConnectedIndexPage = connect(
mapStateToProps,
mapDispatchToProps
)(IndexPage)

export default injectSheet(styles)(ReduxConnectedIndexPage)
18 changes: 2 additions & 16 deletions examples/using-redux/gatsby-browser.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,2 @@
import React from "react"
import { Provider } from "react-redux"

import createStore from "./src/state/createStore"

const store = createStore()

export const wrapRootComponent = ({ Root }) => {
const ConnectedRootComponent = () => (
<Provider store={store}>
<Root />
</Provider>
)

return ConnectedRootComponent
}
import wrapWithProvider from "./wrap-with-provider"
export const wrapRootElement = wrapWithProvider
18 changes: 2 additions & 16 deletions examples/using-redux/gatsby-ssr.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,2 @@
import React from 'react'
import { Provider } from 'react-redux'
import { renderToString } from 'react-dom/server'

import createStore from './src/state/createStore'

export const replaceRenderer = ({ bodyComponent, replaceBodyHTMLString }) => {
const store = createStore()

const ConnectedBody = () => (
<Provider store={store}>
{bodyComponent}
</Provider>
)
replaceBodyHTMLString(renderToString(<ConnectedBody/>))
}
import wrapWithProvider from "./wrap-with-provider"
export const wrapRootElement = wrapWithProvider
9 changes: 9 additions & 0 deletions examples/using-redux/wrap-with-provider.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from "react"
import { Provider } from "react-redux"

import createStore from "./src/state/createStore"

const store = createStore()

// eslint-disable-next-line react/display-name,react/prop-types
export default ({ element }) => <Provider store={store}>{element}</Provider>
11 changes: 1 addition & 10 deletions examples/using-styletron/gatsby-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,5 @@ module.exports = {
siteMetadata: {
title: `Gatsby with Styletron`,
},
plugins: [
`gatsby-plugin-styletron`,
{
resolve: `gatsby-plugin-google-analytics`,
options: {
trackingId: `UA-93349937-2`,
},
},
`gatsby-plugin-offline`,
],
plugins: [`gatsby-plugin-styletron`],
}
13 changes: 1 addition & 12 deletions examples/using-styletron/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,9 @@
"author": "Nadiia Dmytrenko <[email protected]>",
"dependencies": {
"gatsby": "next",
"gatsby-plugin-google-analytics": "next",
"gatsby-plugin-offline": "next",
"gatsby-plugin-styletron": "next",
"lodash": "^4.16.4",
"react": "^16.4.0",
"react-dom": "^16.4.0",
"react-typography": "^0.15.0",
"slash": "^1.0.0",
"styletron-engine-atomic": "^1",
"styletron-react": "^4",
"styletron-react-core": "^1",
"styletron-standard": "^1",
"typography": "^0.15.8",
"typography-breakpoint-constants": "^0.14.0"
"react-dom": "^16.4.0"
},
"keywords": [
"gatsby"
Expand Down
Loading

0 comments on commit 8029c66

Please sign in to comment.