React dropdown not setting state

0 votes
asked Sep 13, 2017 by bkula

I have a parent component that controls all state and a child component that returns a dropdown menu and passes (is supposed to pass, rather) the result of clicking an option up to the parent component and update the parent's state.

Parent:

// We're controlling all of our state here and using children
// components only to return lists and handle AJAX calls.

import React, { Component } from 'react';
import SubList from './SubList';
import StopList from './StopList';

class SubCheck extends Component {

  constructor (props) {
    super(props);
    this.state = {
        selectedSub: null,
        selectedStop: null,
        stops: [],
    };
    this.handleSubSelect.bind(this);
    this.handleStopSelect.bind(this);
    }

    // We want the user to be able to select their specific subway
    // stop, so obviously a different array of stops needs to be 
    // loaded for each subway. We're getting those from utils/stops.json.
    handleSubSelect(event) {
        var stopData = require('../utils/stops');
        var stopsArray = [];
        for (var i = 0; i < stopData.length; i++) {
            var stop = stopData[i];

            if (stop.stop_id.charAt(0) == event.target.onSubSelect) {
                stopsArray.push(stop.stop_name);
            }
        }
        this.setState(() => {
            console.log('setting state');
            return {
                selectedSub: event.target.onSubSelect,
                stops: stopsArray
            }
        });
    }

    handleStopSelect(event) {
        this.setState({selectedStop: event.target.onStopSelect});
    }

    render() {
        return (
            <div>
                <SubList onSubSelect={this.handleSubSelect.bind(this)}/>
                <StopList stops={this.state.stops} onStopSelect={this.handleStopSelect.bind(this)}/>
            </div>
        );
    }
}

export default SubCheck; 

Child:

import React from 'react';
import PropTypes from 'prop-types';

function SubList (props) {
    const subways = ['', '1', '2', '3', '4', '5', '6', 
    'S', 'C', 'B', 'D', 'N', 'Q', 'R', 'L']
    return (
        <select>
            {
                subways.map(subway =>
                    <option key={subway} onClick={() => props.onSubSelect(subway)}>
                        {subway}
                    </option>
                )
            }
        </select>
    )
}
SubList.PropTypes = {
    onSubSelect: React.PropTypes.func.isRequired
};

export default SubList;

When I open the app as is and choose an option from the dropdown menu, two things don't happen that I would expect to happen. One is that the second menu (the one returned by StopList, the code for which isn't included here) is not populated with any data. The second thing is that 'setting state' is not logged to the console. That second thing is leading me to believe that somewhere in my code, I am not correctly passing the option clicked in the dropdown up to my handleSubSelect method and therefore not correctly setting any new state.

3 Answers

0 votes
answered Sep 13, 2017 by mikkel

You have already done the bind, so you don't need that, in fact when the user changes the selection all you are doing is doing the bind

So change this line

<SubList onSubSelect={this.handleSubSelect.bind(this)}/>

to this

<SubList onSubSelect={this.handleSubSelect}/>

and the world should be happier.

You have the same problem with onStopSelect

UPDATE

in the handleSubSelect() method you do this:

   this.setState(() => {
        console.log('setting state');
        return {
            selectedSub: event.target.onSubSelect,
            stops: stopsArray
        }
    });

Which looks a bit messed up, I think it should be this:

   console.log('setting state');
   this.setState({
            selectedSub: event.target.onSubSelect,
            stops: stopsArray
        }
    );
0 votes
answered Sep 13, 2017 by red-fx

You should be binding the methods as:

 this.handleStopSelect = this.handleStopSelect.bind(this);

as on here. Of course changing the element as the following:

  <SubList onSubSelect={this.handleSubSelect}/>

Also instead of event.target.onSubSelect Can you try event.target.value

0 votes
answered Sep 13, 2017 by peter-hurst

You need to use the onChange handler on the select element:

<select onChange={props.onSubSelect}>

Your onSubSelect handler will receive an event, and you'll need to get the selected value from event.target.value.

See docs:

https://facebook.github.io/react/docs/forms.html#the-select-tag

Welcome to Q&A, where you can ask questions and receive answers from other members of the community.
Website Online Counter

...