5

I have the data of products, and I am filtering the data using a search value and then rendering the options using that filtered data. The products data is coming from the global redux store as a prop. For some reason, the dropdown shows data only when the search value is null, when I start typing, the filteredData is updated and the component get re-rendered as well, but the options show no data.

I have checked whether the right filteredData is used to map over the options. The options does not seem to render even when the component is re-rendered.

Please have a look at the code below :

import React from 'react';
// import {useState} from 'react';
import {Select} from 'antd';
import {connect} from 'react-redux';
import {fetchProductsAsync} from 'common/actions/fetchData';

const {Option} = Select;

class SelectOptions extends React.Component {
  state = {
    filteredData: [],
    value: undefined,
  };

  componentDidMount() {
    const {fetchProductsAsync} = this.props;
    fetchProductsAsync();
    const {products} = this.props;
    this.setState({filteredData: products || []});
  }

  componentDidUpdate() {
    console.log(this.state.filteredData);
  }

  filterData = (value) => {
    const {products} = this.props;
    const filData = products.filter((prod) => {
      return prod.name.includes(value);
    });
    // console.log(filData);
    this.setState({filteredData: filData});
  };

  handleSearch = (value) => {
    const {products} = this.props;
    if (value) {
      // this.setState({value});
      this.filterData(value);
      // console.log('yes');
    } else {
      console.log('empty');
      this.setState({filteredData: products});
      this.forceUpdate();
    }
  };

  handleChange = (value) => {
    // console.log(value);
    this.setState({value});
  };
  render() {
    const {others} = this.props;
    // console.log(this.state.filteredData);
    const options = this.state.filteredData.map((item, index) => {
      console.log(item);
      return (
        <Option value={item.value || item[others.key] || item}>
          {others.customTitle ? (
            <text style={{fontSize: 13, fontWeight: 'bold'}}>{item[others.customTitle]}</text>
          ) : (
            item.label || item[others.key] || item
          )}
          {others.dataKeys ? (
            <div className="row" style={{flexWrap: 'wrap'}}>
              {others.dataKeys.map((i) => (
                <text style={{fontSize: 11, marginLeft: 5, marginRight: 5}}>{item[i]}</text>
              ))}
            </div>
          ) : null}
        </Option>
      );
    });
    return (
      <Select
        showSearch
        onSearch={this.handleSearch}
        // placeholder="Select"
        // key={this.state.filteredData.length}
        value={this.state.value}
        onChange={this.handleChange}>
        {options}
      </Select>
    );
  }
}

const mapStateToProps = (state) => {
  return {products: state.data.products || []};
};

export default connect(mapStateToProps, {fetchProductsAsync})(SelectOptions);
Sarthak Saxena
  • 139
  • 4
  • 10

1 Answers1

16

Try setting this prop on the Select component filterOption={false}

Alx Rodav
  • 479
  • 3
  • 10
  • 3
    Hey listen there you wizard, you've saved my life, I've been trying to get this to work since 2 days. Please explain the reason behind doing this. I would like to know how stupid I really am. – Sarthak Saxena Jun 23 '20 at 17:41
  • Can you help me with another problem? dropdowns are fine now but when the option is selected the value does not get updated to the option's value. Thanks. – Sarthak Saxena Jun 23 '20 at 18:36
  • The onChange function is fired and logs the correct value, but when I submit the form it says that this field is required. – Sarthak Saxena Jun 23 '20 at 18:43
  • 1
    Making it simple `filterOption` prop is used to filter locally, It accept boolean | function. If I were you, I would actually the `onSearch` by `filterOption` (because looks like you want to filter locally) – Alx Rodav Jun 24 '20 at 08:50
  • Regarding the the issue with `onChange` & Form submit. Can you please provide some more code? Or maybe ask another Question here Stack Overflow – Alx Rodav Jun 24 '20 at 08:52
  • So I have now used the ```filterOption``` to filter the data, but now I am not able to display the custom data I want to because it is filtering based on the children and now I cannot add multiple children. Can I pass my own prop to use for filter? – Sarthak Saxena Jun 24 '20 at 13:34