2

I have a React Component where I have a Form with multiple Selects. The options of these Select components is passed to the SearchComponent as props.

I want to store the selected options in local state, and once the Submit of the form is pressed it is sent to the parent component that passes a function as a prop - searchStatements.

Since the select is multiple, I have an array of all the options that can be selected and stored in state.

class SearchComponent extends Component {
    state = {
        companies: [],
        years: [],
        currencies: []
    };

    render() {
        return (
            <Form
              onSubmit={(e) => {
                  this.props.searchStatements(this.state.years, 
                          this.state.currencies,this.state.companies);
              }}
            >
                <Select
                  multiple=true
                  value={this.state.companies}
                  options={this.props.companies}
                  onChange={(e) => this.handleSelectChange('companies', e)}
                />
                <Select
                  multiple=true
                  value={this.state.years}
                  options={this.props.years}
                  onChange={(e) => this.handleSelectChange('years', e)}
                />
                <Select
                  multiple=true
                  value={this.state.currencies}
                  options={this.props.currencies}
                  onChange={(e) => this.handleSelectChange('currencies', e)}
                />
            </Form>
        );
    }

    handleSelectChange = (name, v) => {
        if (name === 'currencies') {
            const newArray = this.state.currencies;
            newArray.push(v);
            this.setState({'currencies': newArray});
        } else if (name === 'companies') {
            const newArray = this.state.companies;
            newArray.push(v);
            this.setState({'currencies': newArray});
        } else if (name === 'years') {
            const newArray = this.state.years;
            newArray.push(v);
            this.setState({'years': newArray});
        }
    };
}

The initial state is like this -

state = {
    companies: [],
    years: [],
    currencies: []
};

When a currency USD is added, it should become

state = {
    companies: [],
    years: [],
    currencies: ['USD']
};

Again, when a currency GBP is added, it should become

state = {
    companies: [],
    years: [],
    currencies: ['USD', 'GBP']
};

However, in the handleSelectChange(), after adding a couple of options, it becomes something like this -

state = {
    companies: [['GOOGLE'], ['GOOGLE', 'FACEBOOK']],
    years: [],
    currencies: [['USD'], ['USD', 'GBP']]
};

How do I change handleSelectChange() such that my final output looks something like this -

state = {
    companies: ['GOOGLE', 'FACEBOOK'],
    years: [],
    currencies: ['USD', 'GBP']
};
3
  • Did you debug to see what is the value of v in the handleSelectChange method? Commented Sep 14, 2017 at 10:39
  • It is giving an array - ["USD", "GBP"]. Commented Sep 14, 2017 at 10:43
  • That means you are pushing an array into the existing array, see the problem(and perhaps the solution?) Commented Sep 14, 2017 at 10:44

1 Answer 1

3

Because you use multiple values in the Select your e.g. this.state.years is an array of all years you selected. Hence you should assign the selected values (not push / append). So the handleSelectChange method should be

handleSelectChange = (name, v) => {
    this.setState({[name]: v});
};
Sign up to request clarification or add additional context in comments.

3 Comments

Can you show that without ES6, I am fairly new to it and hence it is very difficult to understand.
I did this - const some = {}; some[name] = v; this.setState(some); and it seems to work. Could you tell me what the difference between the two is.
@yadav_vi Actually the direction I gave were correct bu there was a typo in the implementation of handleSelectChange that I provided. Your solution is correct but with ES6 you can use a shorter one: this.setState({[name]: v})

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.