Search code examples
reactjsautocompletematerial-uionchangesetstate

How to Pass index in the onChange of autocomplete - React material UI


How can we pass index in the onChange method of autocomplete. I am able to set the state of ItemNumber, if I hardcode index as zero. But have trouble setting the index as such. Can anyone guide me.

import React from 'react';
import './style.css';
import Autocomplete from '@material-ui/lab/Autocomplete';

export class Item extends Component {

  constructor(props) {
    super(props);

    this.state = {
        currentItem: [{
            itemNumber: [],
        }],

    };
}

working code for setting the state of 'itemNumber'. But have trouble passing index (instead of currentItem[0], index should be passed. Like currentItem[i]).

onChangeHandleInput  = (event, value) => {            
    let currentItem= [...this.state.currentItem];        
    currentItem[0].itemNumber= value;  
    this.setState({ currentItem});
}


    render() {
        const currentItem= Object.values(this.state.currentItem);

        return (
            <div>
                    {currentItem.map((element, index) => {
                    return (
                        <div className="box">
                                                          
                            <Autocomplete
                            id="itemNumber"
                            value={element.itemNumber}
                            options={this.state.Data}
                            getOptionLabel={option => option}
                            onChange={this.onChangehandleInput}
                            //onChange={() => this.onChangeCaptureAutComItemNo(index)}
                            renderInput={params => (
                                <TextField {...params} fullWidth />
                            )}
                            />

                       </div>
                    );
           </div>
        )
    }

}

Solution

  • For situations like this I prefer to curry the extraneous parameters. Here is the callback that takes the index as an argument and returns a callback function to later take the onChange event and value. The index is closed over in callback scope.

    onChangeHandleInput = index => (event, value) => {            
      const currentAsset = [...this.state.currentAsset];        
      currentAsset[index].serienr = value;  
      this.setState({ currentAsset });
    }
    

    Usage:

    {currentAsset.map((element, index) => {
      return (
        <div className="box">                             
          <Autocomplete
            id="itemNumber"
            value={element.itemNumber}
            options={this.state.Data}
            getOptionLabel={option => option}
            onChange={this.onChangehandleInput(index)}
            renderInput={params => (
              <TextField {...params} fullWidth />
            )}
          />
        </div>
      );
    })}
    

    If you prefer to keep the callback function signature simple you can update it to take the 3 arguments and proxy the change event object and value to the handler.

    onChangeHandleInput = (event, value, index) => {            
      const currentAsset = [...this.state.currentAsset];        
      currentAsset[index].serienr = value;  
      this.setState({ currentAsset });
    }
    

    Usage:

    {currentAsset.map((element, index) => {
      return (
        <div className="box">                             
          <Autocomplete
            id="itemNumber"
            value={element.itemNumber}
            options={this.state.Data}
            getOptionLabel={option => option}
            onChange={(e, val) => this.onChangehandleInput(e, val, index)}
            renderInput={params => (
              <TextField {...params} fullWidth />
            )}
          />
        </div>
      );
    })}