React-select: [V2] Options aren't rerendered directly when parent state is changed

Created on 29 Jul 2018  路  11Comments  路  Source: JedWatson/react-select

I've been facing what appears to be a bug.

I have two components, Parent & Child, with Child containing a Select component. Parent passes down a list of players that can be updated by the user. the options attribute is set as this.props.players so that when a new player is added, it should be also available in the options.

However, the list will only update if the user try to type something in the search field. It will never update if the Select is not searchable. This issue doesn't occur with v1. Find below an example of my problem.

https://codesandbox.io/s/6v0791zj9r

As you can see, the state is properly updated and the props in Child are also correct yet Select doesn't update its options. I'm not going to call this a bug because I don't know if it's supposed to be the intended comportment of V2 or not.

Anyone can help me out there?

Most helpful comment

@WandHerring @lemon-31 @rohmanhm So actually it behaves correctly. Here's what's happening:

  • You are supplying options via props (no matter if that source is dynamic or not),
  • You are passing those options as a options prop to the reactSelect,
  • You are typing a phrase, then you either perform some sort of API call to get options based on this phrase or do some options manipulation somewhere else,
  • Phrase not always match option.label hence reactSelect is filtering those out leaving you with the impression that options didn't update.

In this case, you can disable reactSelect option filtering, since you are handling options yourself. You can do that via returning always true in filterOption callback function:

...some class

filterOption = (/* receives option and rawInput params but we don't need it now */) => true;

render() {

    return (
        <MembersSelect
            autoFocus={true}
            placeholder="some placeholder"
            onInputChange={this.handleInputChange}
            onChange={this.handleSelectionChange}
            filterOption={this.filterOption}
            options={this.props.options}
        />
    );
}
...end of some class

All 11 comments

Hey WandHerring,

I can't help in offering a solution but I can confirm a similar issue. Checkout the issue I created at the link below. Hopefully someone might be able to help us.

(https://github.com/JedWatson/react-select/issues/2894)

@lemon-31 The issue doesn't exist on V1, so I use this version instead at the moment since I don't need the new functionalities.

@WandHerring My thoughts exactly. I'll be using v1 in the meantime

We're running into the same issue as well.

I've got the same issue. My options list is generated from several api calls but only the first option will be displayed. Once that option is selected the list will update to show the rest of the options.

Hi all,

Good news. I figured this out today. It turns out the problem was nothing to do with the "react-select" project but was actually caused by how we are updating our state in React.

React won't see the change made inside the options array unless a new array object is created. There may be a more elegant way to create the new array object but the way I did it was using the "concat" function with an empty array which returns a new array object with the same data.

For the code sandbox in the OP I fixed the issue there by adding the line with the "concat" function as shown below:

addNewPlayerHandler(name) {
  var newPlayer = { value: name, label: name };
  var newPlayersList = this.state.players;
  newPlayersList.push(newPlayer);
  newPlayersList = newPlayersList.concat([]);
  this.setState({ players: newPlayersList });
}

If you want to see another example checkout the issue below where I posted a solution to my own issue that I had created.

https://github.com/JedWatson/react-select/issues/2894

Cheers,

Alex

Hey I just reproduced the same issue and the above solution does not work.

@JedWatson @WandHerring Do you guys know a way to solve this ?

@rohankk2

Hi, do you have any code to share? Another way you can guarantee the state to update is using the "cloneDeep" function when you set the state. Eg:

npm i --save lodash.clonedeep

import cloneDeep = require('lodash/cloneDeep');

this.setState({ players: cloneDeep(newPlayersList) })

@lemon-31 I realized that this was not about options rerendering. Its just that filterOption Is not called when options are changed in parent. I realized this because when I changed the label param of the options that immediately reflects on the dropdown but the filter does not happen until after I interact with the dropdown. I opened another issue. #3244

@WandHerring @lemon-31 @rohmanhm So actually it behaves correctly. Here's what's happening:

  • You are supplying options via props (no matter if that source is dynamic or not),
  • You are passing those options as a options prop to the reactSelect,
  • You are typing a phrase, then you either perform some sort of API call to get options based on this phrase or do some options manipulation somewhere else,
  • Phrase not always match option.label hence reactSelect is filtering those out leaving you with the impression that options didn't update.

In this case, you can disable reactSelect option filtering, since you are handling options yourself. You can do that via returning always true in filterOption callback function:

...some class

filterOption = (/* receives option and rawInput params but we don't need it now */) => true;

render() {

    return (
        <MembersSelect
            autoFocus={true}
            placeholder="some placeholder"
            onInputChange={this.handleInputChange}
            onChange={this.handleSelectionChange}
            filterOption={this.filterOption}
            options={this.props.options}
        />
    );
}
...end of some class

Hello -

In an effort to sustain the react-select project going forward, we're closing old issues.

We understand this might be inconvenient but in the best interest of supporting the broader community we have to direct our efforts towards the current major version.

If you aren't using the latest version of react-select please consider upgrading to see if it resolves any issues you're having.

However, if you feel this issue is still relevant and you'd like us to review it - please leave a comment and we'll do our best to get back to you!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

yrabinov picture yrabinov  路  3Comments

pashap picture pashap  路  3Comments

steida picture steida  路  3Comments

batusai513 picture batusai513  路  3Comments

x-yuri picture x-yuri  路  3Comments