enigma6174
enigma6174

Reputation: 360

How to get the data from dropdown component in React and update state?

I am a beginner React developer and I am stuck at this problem. I am trying to make a user registration form. It contains three text fields and two dropdown buttons. I am able to update the state from the data entered in the text fields but I cannot do the same with the dropbdown buttons. I am sharing the screenshot and the code below of my approach so far.

Before making selection (note React console)

After making selection (note React console)

Here is the code for the same:

NOTE: App.js calls the component Registration.js which in turn calls the component User.js

Registration.js has all the logic to control the form, the state to hold data and the functions to handle forward and backward movement (code incomplete for this).

App.js

import React from 'react';
import './App.css';
import Registration from './components/Registration';

function App() {
  return (
    <div className="App">
      <h1>Hello World</h1>
      <h2>This is a sample app!</h2>
      <h5>Built by Anish Pal!</h5>
      <Registration /> 
    </div>
  );
}

export default App;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Registration.js

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

class Registration extends Component {

    // State to store user data
    state = {
        step: 1,
        userFirstName: '',
        userLastName: '',
        userEmail: '',
        userContact: '',
        userRole: '',
        userExperience: '',
        userEducation: '',
        userAddress: '',
        userBio: ''
    }

    // Move to the next page (component)
    nextStep = () => {
        const { step } = this.state;
        this.setState({
            step: step + 1
        });
    };

    // Move to the previous page (component)
    prevStep = () => {
        const { step } = this.state;
        this.setState({
            step: step + 1
        });
    };

    // Handle input field change (when data is entered)
    handleChange = input => e => {
        this.setState({ [input]: e.target.value });
    };

    render() {

        // Get the step counter
        const { step } = this.state;

        // Get the input fields
        const { userFirstName, userLastName, userEmail, userContact, userRole, userExperience, userEducation, userAddress, userBio } = this.state;

        // Assign a new variable to all the above
        const values =  { userFirstName, userLastName, userEmail, userContact, userRole, userExperience, userEducation, userAddress, userBio };

        // Switch the components based on the step counter
        switch(step) {
            case 1:
                return (
                    <User values={values} handleChange={this.handleChange} nextStep={this.nextStep} />
                );
            default:
                return (
                    <User />
                );
        }

    }
}

export default Registration
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

User.js

import React, { Component } from 'react';
import Card from 'react-bootstrap/Card';
import Container from 'react-bootstrap/Container';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
import Form from 'react-bootstrap/Form';
import Dropdown from 'react-bootstrap/Dropdown';
import DropdownButton from 'react-bootstrap/DropdownButton';

class User extends Component {

    // Handle movement to next component
    continue = e => {
        e.preventDefault();
        this.props.nextStep();
    };

    render() {

        // Extract the props passed from parent
        const { values, handleChange } = this.props;

        // Handle dropdown selections 
        const handleJobSelect = e => {
            console.log(e);
            this.setState({ 
                userRole: e 
            });
        }

        return (
            <div className="d-flex justify-content-center">
                <Card border="primary" style={{ width:"48rem" }}>
                    <Card.Header>REGISTER USER</Card.Header>
                    <Card.Body>
                        <Card.Title>Enter User Details</Card.Title>
                        <Container>
                            <Row>
                                <br />
                            </Row>
                            <Row>
                                <Col>
                                    <Form>
                                        <Form.Control 
                                            type="text" 
                                            placeholder="Enter First Name" 
                                            onChange={handleChange('userFirstName')}
                                            value={values.userFirstName}
                                        />
                                    </Form>
                                </Col>
                                <Col>
                                    <Form>
                                        <Form.Control 
                                            type="text" 
                                            placeholder="Enter Last Name" 
                                            onChange={handleChange('userLastName')}
                                            value={values.userLastName}
                                        />
                                    </Form>
                                </Col>
                            </Row>
                            <Row>
                                <br />
                            </Row>
                            <Row>
                                <Col>
                                    <Form>
                                        <Form.Control 
                                            type="text" 
                                            placeholder="Enter Email ID"
                                            onChange={handleChange('userEmail')}
                                            value={values.userEmail}
                                        />
                                    </Form>
                                </Col>
                            </Row>
                            <Row>
                                <br />
                            </Row>
                            <Row>
                                <Col>
                                    <DropdownButton
                                        id="dropdown-basic-button" 
                                        title="Select Job Role" 
                                        align="start"
                                        onClick={handleChange('userRole')}
                                        //onSelect={handleJobSelect}
                                        value={values.userRole}>
                                    <Dropdown.Item eventKey="Front End Web Developer">Front-End Web Developer</Dropdown.Item>
                                    <Dropdown.Item value="option-2">Back-End Web Developer</Dropdown.Item>
                                    <Dropdown.Item>Data Scientist</Dropdown.Item>
                                    <Dropdown.Item>Data Engineer</Dropdown.Item>
                                    <Dropdown.Item>Dev-Ops</Dropdown.Item>
                                    <Dropdown.Item>Cloud Architect</Dropdown.Item>
                                    </DropdownButton>
                                </Col>
                                <Col>
                                    <DropdownButton id="dropdown-basic-button" title="Select User Experience" align="start">
                                        <Dropdown.Item>No Experience (0-1 years)</Dropdown.Item>
                                        <Dropdown.Item>Some Experience (1-3 years)</Dropdown.Item>
                                        <Dropdown.Item>Medium Experience (3-5 years)</Dropdown.Item>
                                        <Dropdown.Item>Experienced (5-8 years)</Dropdown.Item>
                                        <Dropdown.Item>Specialist (8-10 years)</Dropdown.Item>
                                    </DropdownButton>
                                </Col>
                            </Row>
                        </Container>
                    </Card.Body>
                </Card>
            </div>
        )
    }
}

export default User
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

WHAT I HAVE TRIED

  1. I changed the onClick={handleChange('usereRole')} to onChange={handleChange('userRole')} but that did not generate any change in the state. Using onClick() at least generates some response on the app though I keep getting undefined
  2. I used onSelect={handleJobSelect} and then defined the function as :

const handleChange = e => {
  console.log(e);
}

Using this approach, I was able to successfully get the required value from the list into the console. However, I am still not able to update the state with this value. I need to update the state variable userRole with the item selected from the dropdown button.

Also, if anyone could tell me how to update the title of the button with the selected menu entry, it would be an added bonus (it is good to provide feedback to the user about their selection).

I would also like to mention I am using React-Bootstrap for the components so you guys can refer there for any additional information.

Upvotes: 0

Views: 1111

Answers (1)

Mani Ezhumalai
Mani Ezhumalai

Reputation: 469

You can change onSelect call back like this

onClick={this.handleChange.bind(this)}

inside handleChange function you can access selected value in e

Upvotes: 0

Related Questions