68

I'm trying to do something like the following, however it returns null:

import { Button as styledButton } from 'component-library'

then attempting to render it as:

import React, { PropTypes } from "react";
import cx from 'classNames';

import { Button as styledButton } from 'component-library';

export default class Button extends React.Component {
    constructor(props){
        super(props)
    }
    render() {
        return (
                <styledButton {...this.props}></styledButton>
        )
    }
}

The reason is, I need to import the Button component from a library, and also export a wrapper component with the same name but maintaining the functionality from the imported component. If I leave it at import { Button } from component library then of course, I get a multiple declaration error.

Any ideas?

Jim
  • 1,676
  • 2
  • 13
  • 21
  • 1
    Why you can't change class Button name? – Ved Apr 02 '17 at 19:46
  • 8
    React component should start with a capital letter : dont use `styledButton` but `StyledButton` – topheman Apr 02 '17 at 19:47
  • @Ved I'm using react-styleguidist to display every component, and need to wrap all the components in the component library. If I change the class Button name, the `show code` would have different names for every component in the playground. – Jim Apr 02 '17 at 21:06
  • ya as @topheman said, Alias name should be in pascal case -->AliasName – Aditya Patnaik Aug 03 '20 at 11:55

6 Answers6

131

Your syntax is valid. JSX is syntax sugar for React.createElement(type) so as long as type is a valid React type, it can be used in JSX "tags". If Button is null, your import is not correct. Maybe Button is a default export from component-library. Try:

import {default as StyledButton} from "component-library";

The other possibility is your library is using commonjs exports i.e. module.exports = foo. In this case you can import like this:

import * as componentLibrary from "component-library";

Update

Since this is a popular answer, here a few more tidbits:

export default Button              -> import Button from './button'
                                      const Button = require('./button').default
         
export const Button                -> import { Button } from './button'
                                      const { Button } = require('./button')
         
export { Button }                  -> import { Button } from './button'
                                      const { Button } = require('./button')
         
module.exports.Button              -> import { Button } from './button'
                                      const { Button } = require('./button')

module.exports.Button = Button     -> import { Button } from './button'
                                      const { Button } = require('./button')

module.exports = Button            -> import * as Button from './button'
                                      const Button = require('./button')

chris
  • 5,365
  • 5
  • 38
  • 52
  • Hmm, doesn't seem to work; Button is defined int he library as: ```import { ButtonCore } from 'react-atlas-core'; import { ButtonStyle } from 'react-atlas-default-theme'; export const Button = CSSModules(ButtonCore, ButtonStyle, {allowMultiple: true}); ``` – Jim Apr 02 '17 at 20:26
  • no use of default export; so i have NO IDEA why it wouldn't return anything. – Jim Apr 02 '17 at 20:27
  • i'd probably re-evaluate what you think is going wrong, since that syntax and your intention is valid. What exactly is the error you are getting? – chris Apr 02 '17 at 21:04
  • There was no error, and everything renders without an error. Except that there is no `Button` functionality that is getting imported from the library. – Jim Apr 02 '17 at 21:08
14

Try to import this way

import {default as StyledLibrary} from 'component-library';

I suppose you export

export default StyledLibrary
Marcin Rakowski
  • 141
  • 1
  • 2
6

Careful with capitalisation. Best to always CamelCase.

One:

import Thing from "component";

One with alias:

import {Thing as OtherThing} from "component";

One with alias plus other defaults:

import {Thing as OtherThing}, Stuff, Fluff from "component";

More detailed example

import
{Thing as StyledButton},
{Stuff as Stuffing},
{Fluff as Fluffy},
Wool,
Cotton
from "component";
Harry B
  • 2,511
  • 1
  • 17
  • 40
4

User-Defined Components Must Be Capitalized
https://reactjs.org/docs/jsx-in-depth.html#user-defined-components-must-be-capitalized

change your code to

import { Button as StyledButton } from 'component-library';
....bah...bah....bah  
<StyledButton {...this.props}></StyledButton>
3

No idea why I am not able to alias the import;

As a work around, I ended up doing this:

import React, { PropTypes } from "react";
import * as StyledLibrary from 'component-library';

export default class Button extends React.Component {
    constructor(props){
        super(props)
    }
    render() {
        return (
            <StyledLibrary.Button {...this.props}></StyledLibrary.Button>
        )
    }
}

Thanks all

Jim
  • 1,676
  • 2
  • 13
  • 21
0

note that when you capitalized StyledLibrary and it worked

whereas, in the original question, you did not capitalize styledButton and it did not work

both of these are the expected results with React

so you didn't discover a workaround, you simply discovered the (documented) React way of doing things

steve
  • 166
  • 1
  • 5
  • 1
    Thats interesting... Maybe I didn't catch that before. Could you point to where the documentation is for requiring Components be PascalCase? I was always under the assumption that React wanted component names match their filenames (since they are classes). – Jim Oct 01 '18 at 15:28