stampit-org / react-stampit

A specialized stampit factory for React
131 stars 1 forks source link

Not working with Radium #32

Open nickjohnson-dev opened 9 years ago

nickjohnson-dev commented 9 years ago

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?

troutowicz commented 9 years ago

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.

nickjohnson-dev commented 9 years ago

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.

BerkeleyTrue commented 9 years ago

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.

ianobermiller commented 9 years ago

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.

troutowicz commented 9 years ago

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

ericelliott commented 9 years ago

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?

BerkeleyTrue commented 9 years ago

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).

ianobermiller commented 9 years ago

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.