Search code examples
javascriptreactjsdictionarykey

Reactjs - retrieve attributes from event.target


I have a component which renders Input type='select': (I am using reactstrap)

import React, {Component} from 'react'
import {
    Form,
    FormGroup,
    Input,
    Button,
    Col,
} from 'reactstrap'
import {
    withRouter,
} from 'react-router'
import Context from '../../../../../provider'

class NewPost extends Component {
    constructor(props) {
        super(props)
        this.state = {
            subreddits: [],
            subreddit_selected: '',
            subreddit_id: 0,
            ...
        }
        this.handleSubredditSelect = this.handleSubredditSelect.bind(this)
    }

    componentDidMount() {
        fetch('/api/reddit/r/')
        .then(data => data.json())
        .then(json => {
            this.setState({
                subreddits: json,
                ...
            })
        })
    }

    handleSubredditSelect(event) {
        console.log('selected id: ',event.target.id)
        this.setState({
            subreddit_selected: event.target.value,
            subreddit_id: event.target.id,
        }, () => 
            this.props.history.push(`/${this.state.subreddit_selected}/new/`)
        )
    }

    ...

    render() {
        return (
            <Context.Consumer>
                {context => {
                    return (
                        <React.Fragment>
                            <Form
                                ...
                            >
                                <FormGroup row>
                                    <Col sm={7}>
                                        <Input 
                                            type="select"
                                            onChange={this.handleSubredditSelect}
                                            required
                                        > 
                                            <option key='0' disabled selected>Select an Option</option>
                                            {this.state.subreddits.map((subreddit) => {
                                                return (
                                                    <option key={subreddit.id} id={subreddit.id}>{'r/' + subreddit.name}</option>
                                                )
                                            })}
                                        </Input>
                                    </Col>
                                </FormGroup>
                                ...
                        </React.Fragment>
                        )
                    }}
                </Context.Consumer>
        )
    }
}

export default withRouter(NewPost)

So, I have a function handleSubredditSelect which does the following:

handleSubredditSelect(event) {  
    this.setState({
        subreddit_selected: event.target.value,
        subreddit_id: event.target.id,
    }, () => 
        this.props.history.push(`/${this.state.subreddit_selected}/new/`)
    )
}

In this function I am not getting any value for event.target.id.

I have tried event.target.key as well but that returned an empty string "".

I want to set subreddit_id in state to the selected option's ID


Solution

  • The selecting does not work because event.target in <select> element returns entire tree with options:

    // result of event.target:
    <select>
      <option id="id-1" value="some1">some1</option>
      <option id="id-2" value="some2">some2</option>
      <option id="id-3" value="some3">some3</option>
    </select>
    

    Instead the selected one.


    For accessing the current option element from select you should rely on selectedIndex:

    event.target[event.target.selectedIndex].id 
    

    The code:

    export default class SelectForm extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          value: "some1",
          id: "id-1"
        };
      }
    
      handleChange = event => {
        console.log("event", event.target, event.target.selectedIndex);
    
        this.setState({
          value: event.target.value,
          id: event.target[event.target.selectedIndex].id
        });
      };
    
      render() {
        return (
          <div>
            <select value={this.state.sex} onChange={this.handleChange}>
              <option id="id-1" value="some1">some1</option>
              <option id="id-2" value="some2">some2</option>
              <option id="id-3" value="some3">some3</option>
            </select>
            ID: {this.state.id}
          </div>
        );
      }
    }
    

    Edit 9l814zo9yr