React-select: Tether component isn't working for the latests versions.

Created on 22 Nov 2020  路  2Comments  路  Source: JedWatson/react-select

I was trying use formatOptionLabel prop to modify options' label. Looks like this prop is workable for latest versions. So I had to upgrade the version from v1.3 to v3.1. But with the latest versions (v2.0 to above) I am getting an error if I use tether component:

export default class TetherSelectComponent extends Select {
  constructor(props) {
      super(props);

      this.renderOuter = this._renderOuter;
      this.handleTouchOutside = this._handleTouchOutside;
  }
    componentDidMount() {
      super.componentDidMount.apply(this); // here I am getting error: TypeError: Cannot read property 'apply' of undefined

      this.dropdownFieldNode = ReactDOM.findDOMNode(this);
  }

where with the version v1.3 it is working perfectly and I am getting the dropdown. Here is the example code: https://codesandbox.io/s/react-select-v3-sandbox-forked-4ie9d?file=/example.js
Look like Select class's structure has been changed for the newer ones that's why I am getting that error. Could anyone please guide me what should I do to make the thing workable?

Thanks for your effort.

Most helpful comment

@muradhassan First I have to point out that in React you should not inherit directly from other components. Instead you should use composition to "inherit" from a component.

Continuing with your problem: Instead of trying to change the Select component at its core you should use the provided components framework and the available props to extend it with your desired functionality.

With that you could overwrite the MenuPortal component with a custom one to use the Tether functionality for the dropdown placement.

const MenuPortal = ({...props}) => {
  // `props.controlElement` is a reference to the outer most `<div />` inside the component.
  return (
    <TetherComponent options={tetherOptions} target={props.controlElement}>
      {props.children}
    </TetherComponent>
  );
}

Then we can configure the Select component to use our custom MenuPortal component.

const TetheredSelect = () => (<Select
  components={{ MenuPortal: MenuPortal }}
  menuPortalTarget="tether" // The component needs this prop to render the `MenuPortal` component
  styles={{
    menu: (provided, state) => ({
      ...provided,
      position: 'static' // The menu by itself is absolute positioned.
    })
  }}
/>);

Now we have a Select component with the menu dropdown being managed by Tether.

CodeSandbox example

All 2 comments

@muradhassan First I have to point out that in React you should not inherit directly from other components. Instead you should use composition to "inherit" from a component.

Continuing with your problem: Instead of trying to change the Select component at its core you should use the provided components framework and the available props to extend it with your desired functionality.

With that you could overwrite the MenuPortal component with a custom one to use the Tether functionality for the dropdown placement.

const MenuPortal = ({...props}) => {
  // `props.controlElement` is a reference to the outer most `<div />` inside the component.
  return (
    <TetherComponent options={tetherOptions} target={props.controlElement}>
      {props.children}
    </TetherComponent>
  );
}

Then we can configure the Select component to use our custom MenuPortal component.

const TetheredSelect = () => (<Select
  components={{ MenuPortal: MenuPortal }}
  menuPortalTarget="tether" // The component needs this prop to render the `MenuPortal` component
  styles={{
    menu: (provided, state) => ({
      ...provided,
      position: 'static' // The menu by itself is absolute positioned.
    })
  }}
/>);

Now we have a Select component with the menu dropdown being managed by Tether.

CodeSandbox example

@Rall3n Thanks a lot. It worked perfectly.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

pashap picture pashap  路  3Comments

sampatbadhe picture sampatbadhe  路  3Comments

coder-guy22296 picture coder-guy22296  路  3Comments

geraldfullam picture geraldfullam  路  3Comments

mbonaci picture mbonaci  路  3Comments