styled-components: Cannot create styled-component for component [object Object]

Environment

npx envinfo --system --binaries --npmPackages styled-components,babel-plugin-styled-components --markdown --clipboard

## System:
 - OS: macOS High Sierra 10.13.6
 - CPU: (4) x64 Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz
 - Memory: 160.71 MB / 16.00 GB
 - Shell: 5.3 - /bin/zsh
## Binaries:
 - Node: 8.9.4 - ~/.nvm/versions/node/v8.9.4/bin/node
 - Yarn: 1.10.1 - ~/.nvm/versions/node/v8.9.4/bin/yarn
 - npm: 6.4.1 - ~/.nvm/versions/node/v8.9.4/bin/npm
## npmPackages:
 - styled-components: ^4.1.1 => 4.1.1

Reproduction

As I was trying to upgrade our application from react native 0.55.0 to 0.57.5, I am running into issues with styled-components. Specifically, when I start the app in Android emulator, I get

Cannot create styled-component for component [object Object]

image

(Surprisingly, I do not get such errors in iOS emulator!)

The relevant portion of Typography.js (as shows in the image above):

const BaseTypography = styled.Text`
  color: ${getFontColor};
  ${color}
  ${props => props.capitalize && capitalizeFirstLetter};
  ${space};
`

I am using React 16.6.1, styled-components 4.1.1, @babel/core 7.0.0

Any ideas? I’ve seen https://github.com/styled-components/styled-components/issues/1308 , but I am not sure if it’s relevant.

Steps to reproduce

Expected Behavior

No error

Actual Behavior

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 4
  • Comments: 20 (5 by maintainers)

Most upvoted comments

So, here are what we did, and it somehow worked:

// fails
const ExtendedComponent = styled(OriginalComponent)`
  [Your awesome styles here]
`;

// works
const ExtendedComponent = styled(props => <OriginalComponent {...props} />)`
  [Your awesome styles here]
`;

This seems to only be happening on Debug Android builds, NOT release/production builds.

Here is an example of how we are creating a styled component.

const Divider = styled.View`
  width: 100%
  height: 1
  backgroundColor: ${colors.greyLighter}
`;

Now lets look at how React Native views are represented…

import { View } from "react-native";
console.log("RN View == ", JSON.stringify(View));

For debug builds, this returns View == ', '{"$$typeof":60112}' //object representing a forward ref For release builds, this returns View == ', 'RCTView' //string

Which will configure the styled components for each React Native view here…

If you take a look at the react-is variables, you will see it will initialize the following const…

var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;

This will get set to { _k: 'Symbol(react.forward_ref)_k.i0kqk9t5s8' } for both release and debug builds.

Now lets look at the react-is isValidElementType() function, which is called from here

function isValidElementType(type) {
  return (
    typeof type === "string" || // RELEASE BUILDS WILL EARLY RETURN ON THIS CHECK
    typeof type === "function" ||
    // Note: its typeof might be other than 'symbol' or 'number' if it's a polyfill.
    type === REACT_FRAGMENT_TYPE ||
    type === REACT_CONCURRENT_MODE_TYPE ||
    type === REACT_PROFILER_TYPE ||
    type === REACT_STRICT_MODE_TYPE ||
    type === REACT_SUSPENSE_TYPE ||
    (typeof type === "object" &&
      type !== null &&
      (type.$$typeof === REACT_LAZY_TYPE ||
        type.$$typeof === REACT_MEMO_TYPE ||
        type.$$typeof === REACT_PROVIDER_TYPE ||
        type.$$typeof === REACT_CONTEXT_TYPE ||
        type.$$typeof === REACT_FORWARD_REF_TYPE)) // == 60112
  );
}

For release builds, it will return early after hitting this line, because the tag param is RCTView

typeof type === "string"

But for debug builds, it will end up checking the Symbol references, which are NOT set correctly in debug builds.

ex…

type.$$typeof === `{ _k: 'Symbol(react.forward_ref)_k.i0kqk9t5s8' }`
//instead of what it should be checking, is this...
type.$$typeof === 60112

If I hack react-is to not use the symbols, and simply use the hex values (the defaults), then it works on debug builds.

I am not sure what the correct solution is here… I hope this puts someone on the right track to fixing it 😃

My guess is multiple versions of react-is are installed and the symbols are getting clobbered as mentioned above. If you install it as a dependency in your project, it should dedupe and the issue will go away.