blueberryapps / react-bluekit

Automatically generating a component library from your React components (ES5, ES6, Typescript)
http://bluekit.blueberry.io
MIT License
646 stars 33 forks source link

Support for Redux Connect #122

Open JoseInTheArena opened 7 years ago

JoseInTheArena commented 7 years ago

Hi,

I have a React/Redux app for which I use bluekit. When I use redux's connect() function I get the error below (you'll also find my component's code after the error).

I did some digging and it seems react-docgen doesn't like the fact that I have my component and the component that's produced by calling connect. I installed react-docgen and it seems that if I use the findAllComponentDefinitions resolver, everything works. Is this something that can be added to bluekit, maybe as a flag?

Error parsing component connected/RadioPlayer/RadioPlayer.js: Multiple exported component definitions found. Error: Multiple exported component definitions found.
    at Context.exportDeclaration (/Users/jarzuaga/Documents/development/workspace/univision-fe-new/node_modules/react-docgen/dist/resolver/findExportedComponentDefinition.js:116:13)
    at Context.invokeVisitorMethod (/Users/jarzuaga/Documents/development/workspace/univision-fe-new/node_modules/ast-types/lib/path-visitor.js:344:49)
    at Visitor.PVp.visitWithoutReset (/Users/jarzuaga/Documents/development/workspace/univision-fe-new/node_modules/ast-types/lib/path-visitor.js:196:32)
    at NodePath.each (/Users/jarzuaga/Documents/development/workspace/univision-fe-new/node_modules/ast-types/lib/path.js:101:26)
    at visitChildren (/Users/jarzuaga/Documents/development/workspace/univision-fe-new/node_modules/ast-types/lib/path-visitor.js:219:18)
    at Visitor.PVp.visitWithoutReset (/Users/jarzuaga/Documents/development/workspace/univision-fe-new/node_modules/ast-types/lib/path-visitor.js:204:20)
    at visitChildren (/Users/jarzuaga/Documents/development/workspace/univision-fe-new/node_modules/ast-types/lib/path-visitor.js:246:25)
    at Visitor.PVp.visitWithoutReset (/Users/jarzuaga/Documents/development/workspace/univision-fe-new/node_modules/ast-types/lib/path-visitor.js:204:20)
    at Visitor.PVp.visit (/Users/jarzuaga/Documents/development/workspace/univision-fe-new/node_modules/ast-types/lib/path-visitor.js:133:29)
    at Object.visit (/Users/jarzuaga/Documents/development/workspace/univision-fe-new/node_modules/ast-types/lib/path-visitor.js:101:55)

This is my component's code:

import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import * as actions from 'app/store/actions/player-actions';

import Styles from './RadioPlayer.scss';

/**
  * RadioPlayer widget
  * @param {Object} props component props
  * @returns {JSX}
 */
export const RadioPlayerComponent = ({ playing, streamURL }) => {
  return (
    <div className={Styles.player}>
      {playing && <iframe className={Styles.iframe} title="radio" src={streamURL} />}
    </div>
  );
};

/**
 * propTypes
 * @property {boolean} playing whether or not the radio stream is playing
 * @property {String} streamURL the full URL of the Abacast stream player
 */
RadioPlayerComponent.propTypes = {
  playing: PropTypes.bool.isRequired,
  streamURL: PropTypes.string.isRequired,
};

/**
 * map app state to local props
 * @param  {Object} player the player state from app store
 * @returns {Object} the props to inject to the component
 */
export const stateToProps = ({ player }) => ({
  streamURL: player.abacastUrl,
  playing: player.playPerformance,
});

export default connect(stateToProps, actions)(RadioPlayerComponent);
kjr-lh commented 5 years ago

Just been trying to get bluekit to work with some (lightly) connected components. Ended up resorting to wrapping each component like this:

import React, { Component } from 'react';
import BlueKit from 'react-bluekit';
import componentsIndex from 'src/componentsIndex';
import { Provider } from 'react-redux';
import { createStore } from 'redux';

const store = createStore(s => s, {
  // minimal initial store state
});

const wrappedComponentsIndex = Object.keys(componentsIndex).reduce((nci, key) => {
  const componentEntry = componentsIndex[key];
  const ActualComponent = componentEntry.component;

  return {
    ...nci,
    [key]: {
      ...componentEntry,
      component: props => (
        <Provider store={store}>
          <ActualComponent {...props} />
        </Provider>
      ),
    },
  };
}, {});

export default class PageWithBlueKit extends Component {
  render() {
    return (
      <BlueKit
        componentsIndex={wrappedComponentsIndex}
      />
    );
  }
}