Adding a HOC for using StaticQuery

This commit is contained in:
Jeff Avallone 2019-01-06 13:56:25 -05:00
parent bf35f26d5b
commit 3b11fcb0b6
8 changed files with 57 additions and 57 deletions

View File

@ -4,13 +4,7 @@ exports[`Footer rendering 1`] = `
ShallowWrapper { ShallowWrapper {
Symbol(enzyme.__root__): [Circular], Symbol(enzyme.__root__): [Circular],
Symbol(enzyme.__unrendered__): <Footer Symbol(enzyme.__unrendered__): <Footer
site={ buildId="abc-123"
Object {
"siteMetadata": Object {
"buildId": "abc-123",
},
}
}
t={[Function]} t={[Function]}
/>, />,
Symbol(enzyme.__renderer__): Object { Symbol(enzyme.__renderer__): Object {

View File

@ -1,8 +1,10 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { StaticQuery, graphql } from 'gatsby'; import { graphql } from 'gatsby';
import { withNamespaces, Trans } from 'react-i18next'; import { withNamespaces, Trans } from 'react-i18next';
import withQuery from 'lib/with-query';
import style from './style.module.css'; import style from './style.module.css';
const query = graphql` const query = graphql`
@ -15,7 +17,7 @@ const query = graphql`
} }
`; `;
export const Footer = ({ t, site: { siteMetadata } }) => ( export const Footer = ({ t, buildId }) => (
<footer className={ style.footer }> <footer className={ style.footer }>
<ul className={ style.list }> <ul className={ style.list }>
<li> <li>
@ -33,22 +35,19 @@ export const Footer = ({ t, site: { siteMetadata } }) => (
</li> </li>
</ul> </ul>
<div className={ style.buildId }> <div className={ style.buildId }>
{ siteMetadata.buildId } { buildId }
</div> </div>
</footer> </footer>
); );
Footer.propTypes = { Footer.propTypes = {
t: PropTypes.func.isRequired, t: PropTypes.func.isRequired,
site: PropTypes.shape({ buildId: PropTypes.string.isRequired
siteMetadata: PropTypes.shape({
buildId: PropTypes.string.isRequired
}).isRequired
}).isRequired
}; };
export default withNamespaces()(props => ( export default [
<StaticQuery query={ query } render={ data => ( withQuery(query, {
<Footer { ...props } { ...data } /> toProps: ({ site: { siteMetadata } }) => siteMetadata
) } /> }),
)); withNamespaces()
].reduce((component, fn) => fn(component), Footer);

View File

@ -7,7 +7,7 @@ import { Footer } from 'components/Footer';
describe('Footer', () => { describe('Footer', () => {
test('rendering', () => { test('rendering', () => {
const component = shallow( const component = shallow(
<Footer site={{ siteMetadata: { buildId: 'abc-123' } }} t={ mockT } /> <Footer buildId="abc-123" t={ mockT } />
); );
expect(component).toMatchSnapshot(); expect(component).toMatchSnapshot();
}); });

View File

@ -4,13 +4,7 @@ exports[`Header rendering 1`] = `
ShallowWrapper { ShallowWrapper {
Symbol(enzyme.__root__): [Circular], Symbol(enzyme.__root__): [Circular],
Symbol(enzyme.__unrendered__): <Header Symbol(enzyme.__unrendered__): <Header
site={ banner="testing"
Object {
"siteMetadata": Object {
"banner": "testing",
},
}
}
/>, />,
Symbol(enzyme.__renderer__): Object { Symbol(enzyme.__renderer__): Object {
"batchedUpdates": [Function], "batchedUpdates": [Function],
@ -540,13 +534,7 @@ exports[`Header rendering with no banner 1`] = `
ShallowWrapper { ShallowWrapper {
Symbol(enzyme.__root__): [Circular], Symbol(enzyme.__root__): [Circular],
Symbol(enzyme.__unrendered__): <Header Symbol(enzyme.__unrendered__): <Header
site={ banner={false}
Object {
"siteMetadata": Object {
"banner": false,
},
}
}
/>, />,
Symbol(enzyme.__renderer__): Object { Symbol(enzyme.__renderer__): Object {
"batchedUpdates": [Function], "batchedUpdates": [Function],

View File

@ -1,10 +1,11 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Link, StaticQuery, graphql } from 'gatsby'; import { Link, graphql } from 'gatsby';
import { withNamespaces, Trans } from 'react-i18next'; import { withNamespaces, Trans } from 'react-i18next';
import GitlabIcon from 'react-feather/dist/icons/gitlab'; import GitlabIcon from 'react-feather/dist/icons/gitlab';
import withQuery from 'lib/with-query';
import LocaleSwitcher from 'components/LocaleSwitcher'; import LocaleSwitcher from 'components/LocaleSwitcher';
import style from './style.module.css'; import style from './style.module.css';
@ -19,10 +20,10 @@ const query = graphql`
} }
`; `;
export const Header = ({ site: { siteMetadata } }) => ( export const Header = ({ banner }) => (
<header <header
className={ style.header } className={ style.header }
data-banner={ siteMetadata.banner || null }> data-banner={ banner || null }>
<h1> <h1>
<Link to="/">Regexper</Link> <Link to="/">Regexper</Link>
</h1> </h1>
@ -49,18 +50,15 @@ export const Header = ({ site: { siteMetadata } }) => (
); );
Header.propTypes = { Header.propTypes = {
site: PropTypes.shape({ banner: PropTypes.oneOfType([
siteMetadata: PropTypes.shape({ PropTypes.bool,
banner: PropTypes.oneOfType([ PropTypes.string
PropTypes.bool, ]).isRequired
PropTypes.string
]).isRequired
}).isRequired
}).isRequired
}; };
export default withNamespaces()(props => ( export default [
<StaticQuery query={ query } render={ data => ( withQuery(query, {
<Header { ...props } { ...data } /> toProps: ({ site: { siteMetadata } }) => siteMetadata
) } /> }),
)); withNamespaces()
].reduce((component, fn) => fn(component), Header);

View File

@ -6,14 +6,14 @@ import { Header } from 'components/Header';
describe('Header', () => { describe('Header', () => {
test('rendering', () => { test('rendering', () => {
const component = shallow( const component = shallow(
<Header site={{ siteMetadata: { banner: 'testing' } }} /> <Header banner="testing" />
); );
expect(component).toMatchSnapshot(); expect(component).toMatchSnapshot();
}); });
test('rendering with no banner', () => { test('rendering with no banner', () => {
const component = shallow( const component = shallow(
<Header site={{ siteMetadata: { banner: false } }} /> <Header banner={ false } />
); );
expect(component).toMatchSnapshot(); expect(component).toMatchSnapshot();
}); });

View File

@ -20,11 +20,11 @@ ShallowWrapper {
"nodeType": "class", "nodeType": "class",
"props": Object { "props": Object {
"children": Array [ "children": Array [
<LoadNamespace(Component) />, <LoadNamespace(WithQuery(Header)) />,
<SentryBoundary> <SentryBoundary>
Example content Example content
</SentryBoundary>, </SentryBoundary>,
<LoadNamespace(Component) />, <LoadNamespace(WithQuery(Footer)) />,
], ],
}, },
"ref": null, "ref": null,
@ -68,11 +68,11 @@ ShallowWrapper {
"nodeType": "class", "nodeType": "class",
"props": Object { "props": Object {
"children": Array [ "children": Array [
<LoadNamespace(Component) />, <LoadNamespace(WithQuery(Header)) />,
<SentryBoundary> <SentryBoundary>
Example content Example content
</SentryBoundary>, </SentryBoundary>,
<LoadNamespace(Component) />, <LoadNamespace(WithQuery(Footer)) />,
], ],
}, },
"ref": null, "ref": null,

21
src/lib/with-query.js Normal file
View File

@ -0,0 +1,21 @@
import React from 'react';
import { StaticQuery } from 'gatsby';
const withQuery = (query, options = {}) => Component => {
const { toProps } = {
toProps: data => data,
...options
};
const displayName = Component.displayName || Component.name || 'Component';
const wrapped = props => (
<StaticQuery query={ query } render={ data => (
<Component { ...props } { ...toProps(data) } />
) } />
);
wrapped.displayName = `WithQuery(${ displayName })`;
return wrapped;
};
export default withQuery;