Kousha Kousha - 23 days ago 8
React JSX Question

React clone component (stateless or stateful) to pass additional props

I want to clone/extend a React component (without knowing if it is statefull or stateless) and pass it props:

const Foo = (props) => {
return (
<div>foo</div>
);
}

class Bar extends React.Component {
render() {
return (
<div>bar</div>
)
}
}


The problem is, these two variables
Foo
and
Bar
should be handled differently:

const FooExtended = (props, context) => {
return Foo(_.extend(props, additionalProps), context);
}

class BarExtended extends Bar {
constructor(props, context) {
super(_.extend(props, additionalProps), context);
}
}


And there is no simple way to know if a variable
Component
is Stateless or Statefull without doing hacky
toString
regex tests.

React.cloneElement/createElement
fails on these giving me the following error:


React.createElement: type is invalid -- expected a string (for
built-in components) or a class/function (for composite components)
but got: object. You likely forgot to export your component from the
file it's defined in.


So is there a simple way that I can do just
cloneComponent(originalComponent, additionalProps)
?

Answer Source

And there is no simple way to know if a variable Component is Stateless or Statefull [...]

And I think this is one of the reasons why it was required to extend React.Component at some point, to make it easier to distinguish between those two. Because React itself has to be able to distinguish between them since classes cannot be instantiated without new.

You could do the following:

function cloneComponent(originalComponent, additionalProps) {
   if (originalComponent.prototype instanceof React.Component) {
     return class extends originalComponent {
       constructor(props, context) {
         super(_.extend(props, additionalProps), context);
       }
     };
   }
   return (props, context) => {
     return originalComponent(_.extend(props, additionalProps), context);
   };
}

Because Foo.protoype instanceof React.Component is true.


However, I think it is more common to do something like this instead:

function addProps(Component, additionalProps) {
  return props => <Component {...props} {...additionalProps} />;
}

Then there is no need to distinguish between stateful and stateless components.