Search code examples
reactjsecmascript-6babeljsstatelessarrow-functions

Unexpected token syntax error in a stateless function using arrow syntax


Here is the error message:

SyntaxError: <local path>/Icon.jsx: Unexpected token (13:2)
  11 | 
  12 |   return (
> 13 |     <{props.component} onclick=props.onClick styleName=props.classNames style=props.style/>
     |      ^
  14 |   );
  15 | };

I can't seem to figure out how to fix this syntax error in the stateless function return, here is the code:

import React from 'react';
import CSSModules from 'react-css-modules';
import styles from './Icon.css';

const Icon = (props) => {
  let classNames = `icon-${props.name}`;

  if (props.className) {
    classNames = `${classNames} ${props.className}`;
  }

  return (
    <{props.component} onclick={props.onClick} styleName={props.classNames} style={props.style} />
  );
};    

Icon.propTypes = {
  name: React.PropTypes.string.isRequired,
  className: React.PropTypes.string,
  onClick: React.PropTypes.func,
  component: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.func]),
  style: React.PropTypes.object,
};

Icon.defaultProps = {
  component: 'span',
};

export default CSSModules(Icon, styles, { allowMultiple: true, errorWhenNotFound: false });

And here is the .babelrc config:

{
  "presets": [
    "es2015",
    "stage-0",
    "react"
  ],
  "plugins": [
    [
      "transform-runtime",
      "react-intl", {
        "messagesDir": "./build/messages",
        "enforceDescriptions": false
      }
    ]
  ]
}

And here is the very same component without a stateless function or arrow syntax which is working fine:

import React from 'react';
import CSSModules from 'react-css-modules';
import styles from './Icon.css';

class Icon extends React.Component {

  static defaultProps = {
    Component: 'span',
  };

  /**
   * render component
   * @return {object}
   */
  render() {
    const {
      Component,
      name,
      className,
      style,
      onClick,
    } = this.props;
    let classNames = `icon-${name}`;

    if (className) {
      classNames = `${classNames} ${className}`;
    }
    return <Component onClick={onClick} styleName={classNames} style={style} />;
  }
}

Icon.propTypes = {
  name: React.PropTypes.string.isRequired,
  className: React.PropTypes.string,
  onClick: React.PropTypes.func,
  Component: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.func]),
  style: React.PropTypes.object,
};


export default CSSModules(Icon, styles, { allowMultiple: true, errorWhenNotFound: false });

I've tried all the related answers without success, any suggestions?


Solution

  • You just need to copy what you did before const Component = props.component

    and then do <Component onClick={props.onClick} styleName={props.classNames} style={props.style} />

    React distinguishes components from html by checking to see if the element is capitalized. In your case since you are just doing `<{props.component}' which react wont pick up as being a component and it wont know how to parse it as an html element either.