'Creating styled-component with React.createElement

I would like to create a styled-component with a function, taking element as an argument, which I create with React.createElement call.

const StyledComponent = (element) => styled(element)`
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    `;

const myComponent = (props) => {
    const element = React.createElement('div', null, `Hello World!`);
    return (
        StyledComponent(element)
    );
}

This results in following error:

Uncaught Error: Cannot create styled-component for component: [object Object].

I am probably missing something, but am unable to figure it out.



Solution 1:[1]

Felix answer was almost right, but you still need to pass the className property in the inline component function in order to get the styles defined in your styled component applied.

I was able to find the right answer in this thread, I decided to use the JSX-syntax, If you need to pass refs, use React.cloneElement instead.

Complete example:

const StyleMyElement = (Element) => styled(({ className }) => <Element.type {...Element.props} className={className} />)`
    position: absolute;
    top: 0;
    ...
`;

...

const element = () => React.createElement('div', null, `Hello World!`);
const StyledComponent = StyleMyElement(element);

return (
    <StyledComponent />
)

Solution 2:[2]

You can't create a HOC of a rendered React node. The following line is a render call:

const element = React.createElement('div', null, `Hello World!`);

// this is the same as:
const element = <div >Hello World</div>

What you may want is to replace the createElement with an actual functional component:

const element = () => React.createElement('div', null, `Hello World!`);

// this is the same as:
const element = () => <div >Hello World</div>

Now you can create a styled component and render it. Full (relevant) code:

const element = () => React.createElement('div', null, `Hello World!`);
const SComponent = StyledComponent(element);

return React.createElement(SComponent);

Solution 3:[3]

As of styled-components v4 you can just use the as prop to do this easily.

From the docs:

If you want to keep all the styling you've applied to a component but just switch out what's being ultimately rendered (be it a different HTML tag or a different custom component), you can use the "as" prop to do this at runtime.

import styled from "styled-components";

const Component = styled.div`
  color: red;
`;

render(
  <Component
    as="button"
    onClick={() => alert('It works!')}
  >
    Hello World!
  </Component>
)

Solution 4:[4]

Let make things simple import styled from 'styled-component'//import library for making styled components

If for intance would like to create a styled component based on a <p></p> you would do lile this:

const MyP=styled.p color:red; font-size:10px; font-weight:bold ;

You can ads as much css defintion as you want. Now to use it:

const MyComponent=()=>{ <MyP> Hello </MyP> }

Here instead of 'MyP' you could use 'p'(not styled).

It will also work for the const MyComponent=React.creatElement(MyP,null,'Hello'); Hope it helped

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 karlitos
Solution 2 Felix
Solution 3 benmneb
Solution 4 Christian Lisangola