react-stampit icon indicating copy to clipboard operation
react-stampit copied to clipboard

Not working with Radium

Open nickjohnson-dev opened this issue 9 years ago • 8 comments

I'm a big fan of what react-stampit represents in terms of application structure, and I began to use it in a project recently to become more familiar with React. Another thing I found exciting about React was the possibility of proper scoping for styles, especially with the extra features of a library like Radium.

Unfortunately when trying something similar to the following code, I found that components created through react-stampit factories weren't working when they are wrapped in Radium().

import React from 'react';
import Radium from 'radium';
import component from 'react-stampit';

const mount = document.querySelector('.mount'),
    style = {backgroundColor: '#36d'},
    appFactory = React => component(React, {
        render() {
            return <h1 style={style}>Heya</h1>;
        }
    }),
    App = Radium(appFactory(React));

React.render(<App />, mount);

This throws the following exception on render:

image

From sorting through the source code a bit, the problem seems to stem from Radium checking the prototype of the component, and the prototype resolving to Factory instead of what Radium expects.

Is there some general guidance for using react-stampit components with Radium or is it an incompatibility between the two APIs?

nickjohnson-dev avatar Jul 30 '15 20:07 nickjohnson-dev

Without having looked at Radium's source, it sounds like it expects React components to be constructor functions. If that is true, then yes, this is an API incompatibility.

troutowicz avatar Jul 31 '15 11:07 troutowicz

I'm not entirely familiar with the inner workings of Radium either, but after trying to step through some of the code in Chrome, I would say that you're probably correct.

nickjohnson-dev avatar Jul 31 '15 16:07 nickjohnson-dev

unfortunately, there are going to be a lot of incompatibilities with other libraries in the react ecosystem as well. For instance, some of the eslint-plugin-react rules do not work.

BerkeleyTrue avatar Jul 31 '15 17:07 BerkeleyTrue

Radium expects the component to be something it can inherit from (see Enhancer). Not sure I understand exactly what the problem is. Radium doesn't "check the prototype"; the most it does with the prototype is copy statics to avoid issues on IE10.

ianobermiller avatar Aug 31 '15 21:08 ianobermiller

I hadn't investigated this any further, but I'll take a look now. Thanks @ianobermiller.

troutowicz avatar Sep 01 '15 00:09 troutowicz

Without having looked at Radium's source, it sounds like it expects React components to be constructor functions. If that is true, then yes, this is an API incompatibility.

That looks like it is the issue, yes. I'm afraid that React took a bad turn when they started saying class is OK. The sad thing about class is that it always seems to find a way to infect everything it touches. );

Does React.createClass() return a constructor function? How does Radium (and any other lib in the React ecosystem) work with .createClass()?

@BerkeleyTrue Which rules don't work, specifically, and why?

ericelliott avatar Sep 01 '15 21:09 ericelliott

jsx-sort-propTypes

There may be more. Not sure why it didn't work, but its probably due to the plugin looking for React. createClass in the AST (just a guess).

BerkeleyTrue avatar Sep 07 '15 18:09 BerkeleyTrue

Does React.createClass() return a constructor function? How does Radium (and any other lib in the React ecosystem) work with .createClass()?

Yes, createClass does return a constructor function. Radium works just the same with createClass as with class extends.

ianobermiller avatar Sep 07 '15 20:09 ianobermiller