styled-components / styled-components

Visual primitives for the component age. Use the best bits of ES6 and CSS to style your apps without stress đź’…
https://styled-components.com
MIT License
40.46k stars 2.5k forks source link

Theme not being provided as prop after upgrading to v4 - error occurred in the <Context.Consumer> component. #2724

Closed joetidee closed 5 years ago

joetidee commented 5 years ago

I have just upgraded from v3 to v4 and now when running my Jest/Enzyme tests I get the following messages:

TypeError: Cannot read property 'dark' of undefined

  11 | 
  12 |     > svg {
> 13 |         fill: ${({ color, scheme, theme }) => (color !== '' ? color : theme.icon[scheme].color)};
     |                                                                       ^
  14 |         height: ${({ height }) => remAuto(height)};
  15 |         width: ${({ width }) => remAuto(width)};
  16 |     }

  at Object.<anonymous>._styledComponents.default.div.withConfig.height (../tidee-life-ui/src/icon.js:13:71)
  at flatten (../tidee-life-ui/node_modules/styled-components/dist/styled-components.cjs.js:1305:21)
  at flatten (../tidee-life-ui/node_modules/styled-components/dist/styled-components.cjs.js:1285:16)
  at ComponentStyle.generateAndInjectStyles (../tidee-life-ui/node_modules/styled-components/dist/styled-components.cjs.js:1494:19)
  at StyledComponent.generateAndInjectStyles (../tidee-life-ui/node_modules/styled-components/dist/styled-components.cjs.js:2113:36)
  at StyledComponent.renderInner (../tidee-life-ui/node_modules/styled-components/dist/styled-components.cjs.js:2018:33)
  at updateContextConsumer (node_modules/react-dom/cjs/react-dom.development.js:15484:19)
  at beginWork (node_modules/react-dom/cjs/react-dom.development.js:15672:14)
  at performUnitOfWork (node_modules/react-dom/cjs/react-dom.development.js:19312:12)
  at workLoop (node_modules/react-dom/cjs/react-dom.development.js:19352:24)
  at renderRoot (node_modules/react-dom/cjs/react-dom.development.js:19435:7)
  at performWorkOnRoot (node_modules/react-dom/cjs/react-dom.development.js:20342:7)
  at requestWork (node_modules/react-dom/cjs/react-dom.development.js:20090:7)
  at scheduleWork (node_modules/react-dom/cjs/react-dom.development.js:19911:5)
  at scheduleRootUpdate (node_modules/react-dom/cjs/react-dom.development.js:20572:3)
  at updateContainerAtExpirationTime (node_modules/react-dom/cjs/react-dom.development.js:20600:10)
  at updateContainer (node_modules/react-dom/cjs/react-dom.development.js:20657:10)
  at ReactRoot.Object.<anonymous>.ReactRoot.render (node_modules/react-dom/cjs/react-dom.development.js:20953:3)
  at node_modules/react-dom/cjs/react-dom.development.js:21090:14
  at unbatchedUpdates (node_modules/react-dom/cjs/react-dom.development.js:20454:14)
  at legacyRenderSubtreeIntoContainer (node_modules/react-dom/cjs/react-dom.development.js:21086:5)
  at Object.render (node_modules/react-dom/cjs/react-dom.development.js:21155:12)
  at render (node_modules/enzyme-adapter-react-16/src/ReactSixteenAdapter.js:429:26)
  at fn (node_modules/enzyme-adapter-react-16/src/ReactSixteenAdapter.js:346:37)
  at Object.batchedUpdates$1 [as unstable_batchedUpdates] (node_modules/react-dom/cjs/react-dom.development.js:20439:12)
  at Object.act (node_modules/react-dom/cjs/react-dom-test-utils.development.js:1161:27)
  at act (node_modules/enzyme-adapter-react-16/src/ReactSixteenAdapter.js:346:13)
  at Object.wrapAct [as render] (node_modules/enzyme-adapter-react-16/src/ReactSixteenAdapter.js:415:16)
  at new render (node_modules/enzyme/src/ReactWrapper.js:115:16)
  at Object.mount (node_modules/enzyme/src/mount.js:10:10)
  at Object.<anonymous>.exports.mountWithCustomWrappers (node_modules/enzyme-custom-wrappers/src/custom-wrappers.ts:77:60)
  at ComponentBuilder._callee3$ (src/utilities/integration-testing/component-builder.js:93:35)
  at tryCatch (node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:45:40)
  at Generator.invoke [as _invoke] (node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:271:22)
  at Generator.prototype.(anonymous function) [as next] (node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:97:21)
  at asyncGeneratorStep (node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:24)
  at _next (node_modules/@babel/runtime/helpers/asyncToGenerator.js:25:9)

console.error node_modules/react-dom/cjs/react-dom.development.js:17117 The above error occurred in the component: in StyledComponent in iconStyledIcon in Icon in StyledComponent in loadingStyledIcon in div in StyledComponent in loading__StyledLoading in Loading (created by Boxes) in Boxes (created by InjectIntl(Boxes)) in InjectIntl(Boxes) (created by Route) in Route (created by withRouter(InjectIntl(Boxes))) in withRouter(InjectIntl(Boxes)) (created by Connect(withRouter(InjectIntl(Boxes)))) in Connect(withRouter(InjectIntl(Boxes))) in Router (created by BrowserRouter) in BrowserRouter (created by Wrapper) in ThemeProvider (created by Theme) in Theme (created by Wrapper) in IntlProvider (created by LocaleProviderWrapper) in LocaleProviderWrapper (created by Connect(LocaleProviderWrapper)) in Connect(LocaleProviderWrapper) (created by Wrapper) in Provider (created by Wrapper) in Wrapper (created by WrapperComponent) in WrapperComponent

This seems to suggest that the theme prop is not getting to my Icon component. Nothing has changed in the way that I am supplying the theme to my components in the tests and they were all working before upgrading.

const component = mount(<Wrapper store={store}><RootComponent {...props} /></Wrapper>, rootWrappers);

With Wrapper being:

import ThemeProvider from "../../theme/Theme.jsx";
class Wrapper extends Component {
    getStore() {
        return this.props.store;
    }

    render() {
        return (
            <Provider store={this.props.store}>
                <LocaleProviderWrapper>
                    <ThemeProvider>
                        <BrowserRouter>{this.props.children}</BrowserRouter>
                    </ThemeProvider>
                </LocaleProviderWrapper>
            </Provider>
        );
    }
}

and ThemeProvider being:

import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import { createGlobalStyle, ThemeProvider } from 'styled-components';
import theme from 'tidee-life-theme';
const GlobalStyle = createGlobalStyle`${theme.global}`;

class Theme extends Component {
    constructor() {
        super();
        this.state = {
            theme,
        };
    }

    render() {
        return (
            <Fragment>
                <GlobalStyle />
                <ThemeProvider theme={this.state.theme}>
                    {this.props.children}
                </ThemeProvider>
            </Fragment>
        );
    }
}

Theme.propTypes = {
    children: PropTypes.element.isRequired,
};

export default Theme;

Packages used: react 16.8.6 enzyme 3.10.0 jest: 24.9.0 jest-styled-components: 6.3.3 styled-components: 4.3.2

quantizor commented 5 years ago

You might have multiple copies of styled-components loading in your tests... happens often. You can use moduleNameMapper in jest to dedupe it.

joetidee commented 5 years ago

OK, i added:

moduleNameMapper: {
    '^styled-components$': '<rootDir>/node_modules/styled-components'
},

and the tests are now working - thank you @probablyup . Why does Jest load multiple copies? Is this specific to styled components, else how is it not loading multiple copies of other modules used?

quantizor commented 5 years ago

Probably you’re using two libraries with s-c in dependencia but it’s only meant to be installed once. The shared library should specify it as a peer dependency

On Sun, Aug 25, 2019 at 7:18 AM Joe notifications@github.com wrote:

OK, i added:

moduleNameMapper: { '^styled-components$': '/node_modules/styled-components' },

and the tests are now working - thank you @probablyup https://github.com/probablyup . Why does Jest load multiple copies? Is this specific to styled components, else how is it not loading multiple copies of other modules used?

— You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub https://github.com/styled-components/styled-components/issues/2724?email_source=notifications&email_token=AAELFVVBBPBFUXUZTJM73JLQGJTB3A5CNFSM4IOKQUS2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD5CRQTY#issuecomment-524621903, or mute the thread https://github.com/notifications/unsubscribe-auth/AAELFVTLTUATTQNLZ6JZUZDQGJTB3ANCNFSM4IOKQUSQ .

joetidee commented 5 years ago

Probably you’re using two libraries with s-c in dependencia but it’s only meant to be installed once. The shared library should specify it as a peer dependency … On Sun, Aug 25, 2019 at 7:18 AM Joe @.***> wrote: OK, i added: moduleNameMapper: { '^styled-components$': '/node_modules/styled-components' }, and the tests are now working - thank you @probablyup https://github.com/probablyup . Why does Jest load multiple copies? Is this specific to styled components, else how is it not loading multiple copies of other modules used? — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub <#2724?email_source=notifications&email_token=AAELFVVBBPBFUXUZTJM73JLQGJTB3A5CNFSM4IOKQUS2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD5CRQTY#issuecomment-524621903>, or mute the thread https://github.com/notifications/unsubscribe-auth/AAELFVTLTUATTQNLZ6JZUZDQGJTB3ANCNFSM4IOKQUSQ .

So, I am using a monorepo with a ui and web layer. Both layers have styled-components as dependencies. The web layer also has the ui layer as a dependency. So, what, if anythgin do I change to a peerDependency?

quantizor commented 5 years ago

The upstream packages should have styled-components as a peerDependency and the downstream ones should declare it as a dependency.