1

I am using es6 classes and react-select to create a dropdown menu and want to replace the component for the react-select menu icon. My methods are static, so I expect to be able to use them by calling them using the class name, in this case CustomSelectDropDown, but I keep getting this error:

React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: . Did you accidentally export a JSX literal instead of a component? in Select (created by StateManager)

My code looks like this:

import React, { Component } from 'react';
import Select, { components } from 'react-select';
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCaretDown } from "@fortawesome/free-solid-svg-icons";
import { library } from "@fortawesome/fontawesome-svg-core";
library.add(faCaretDown);

export class CustomSelectDropDown extends Component {
    static Placeholder(props) {
        return <components.Placeholder {...props} />;
    }

    static CaretDownIcon () {
        return <FontAwesomeIcon icon="caret-down" />;
    };

    static DropdownIndicator(props) {
        return (
            <components.DropdownIndicator {...props}>
                { this.CaretDownIcon() }
            </components.DropdownIndicator>
        );
    };

    render() {
        return (
            <div className="customSelect" id={this.props.idName}>
                <div className="fb--w60">
                    <Select 
                        ...
                        components={{ 
                            Placeholder: CustomSelectDropDown.Placeholder(), 
                            DropdownIndicator: CustomSelectDropDown.DropdownIndicator() }}
                        ...
                    />
                </div>
            </div>
        );
    }
}

export default CustomSelectDropDown;

What I am doing incorrectly? I thought this was the proper way of using static methods.

If I try to change the DropdownIndicator's call this.CaretDownIcon() to CustomSelectDropDown.CaretDownIcon() instead, then I get the following a different error, shown below, but I think using this.CaretDownIcon() should be the right way.

Uncaught Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. Check the render method of Select.

Perhaps this has to do more with react-select than JS/reactjs/es6?

1 Answer 1

1

First, I don't know that your components there need to be static methods. They don't need to be properties of your component, they just need to be available to the class itself. You might even want them defined outside of your class definition all together, so that they aren't publicly accessible in any way.

const CaretDownIcon = () => <FontAwesomeIcon icon="caret-down" />;

// ...other definitions

export class CustomSelectDropDown extends Component {
  // ...
  render() {
    // ... getting whatever prop and state values you need
    return (
      <Select
        {...otherProps}
        components={{
          Placeholder: MyPlaceholder,
          // ... etc, etc
        }}

Second, in your CustomDropdownIndicator, you're trying to insert a React component using a method, when all you have to do is put in the tag.

const CustomDropdownIndicator = (props) => (
  <components.DropdownIndicator {...props}>
    <CaretDownIcon />
  </components.DropdownIndicator>
);

I don't think your issue was in how to call a static method. ClassWithStaticMethod.staticMethod() or this.constructor.staticMethod() is the right syntax. I think your issue was you were trying to invoke the method, in the components config, rather than simply passing those stateless components in to the config.

<Select 
  ...
  components={{ 
    Placeholder: CustomSelectDropDown.Placeholder, 
    DropdownIndicator: CustomSelectDropDown.DropdownIndicator 
  }}
  ...
/>

That said, static methods can be called on the class without having an instance of the class, so the question again becomes "Should this really be a static method? Or are these bits only necessary within my class?"

Sign up to request clarification or add additional context in comments.

1 Comment

thanks @Steve, I believe these functions are actually stateless components, so I solved my issue by moving them into their own files, and import them as components. What I don't understand is why using static keyword for the functions causes issues. I mean, I should be able to call them ClassWithStaticMethod.staticMethod(), but this did not work. I defining my CaretDownIcon as a component, even thought it does in fact only return the icon.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.