简体   繁体   中英

Get selected value from a loop generated drop-down-menu in React

I would like to know what is the proper way to create several drop-down-menus ( <select> ), with a loop, where i can then access their selected value through a button. I tried to recreate what I currently have in my code so i hope this is enough.

(The reason i put <select> elements in an array is because i use different arrays to generate a table with rows in my original code.)

Currently getValue() , that is trying to get the value from the 1st drop-down-menu, prints '' which is the initial value, even when i change the value from the menu. I think the problem is that putting them in array is causing them not to update their own value when changed. Is there a way to get around this problem?

This code is also causing this.state.value to only be set on the last drop-down-menu that was changed. I understand why this is happening but i don't know how to get around it.

interface Props extends PanelProps<Options> {}

export class TablePanel extends Component<Props,{value: string, staterows:JSX.Element[]}> {
  constructor(props: Props) {
    super(props);
    this.handleUniqueSelect = this.handleUniqueSelect.bind(this)
    this.state = {value: '', staterows:[] }
  }

  handleUniqueSelect(val:any){
     this.setState({value: val.currentTarget.value})    
  }

  populateRows(){
     let rows:any = []
     for(let index = 0; index < 10; index++) {
        rows.push(<select value={this.state.value} onChange={this.handleUniqueSelect }>
                        <option value="volvo">Volvo</option>
                        <option value="saab">Saab</option>
                        <option value="mercedes">Mercedes</option>
                        <option value="audi">Audi</option>
                     </select>
                 );
     }
     this.setState({staterows: rows})    
  } 



 getValue(){
   if(this.state.staterows.length === 0)
    this.populateRows()
   console.log(this.state.staterows[0].props.value);
 }

 render(){
  
    return (
           <div>
            {this.state.staterows}     
             <button type='button' onClick={e=>this.getValue()} >Button</button>
           </div>   
          );
  }
}

I've added the example in Sandbox . I changed console.log(this.state.staterows[0].props.value); to console.log(this.state.staterows[0]); because it had issues finding properties of unknown type.

Here's a working codesandbox .

Note that you can return markup directly from a function without the need to store in state first, this is what I did with populateRows .

Value of each dropdown should be mapped to a specific index of an array in the state (or some other similar data structure to store multiple values). This maps a given dropdown's value to a specific item in an array: value={this.state.values[index]}

HTML elements in a map function in React must have unique key attribute so that React can correctly see what has changed between renders (there's actually more to that, but it's another topic). In my case I chose the index just for the example, but you can google about this and see how to correctly choose a unique key (rather use some known ID).

Initially the array in the state is empty so you get [] for the stringified value at the bottom. As you change values in dropdown the array will be filled/modified.

I hope this helps and of course, ask if there's something unclear.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM