Reputation: 360
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.
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
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 undefinedonSelect={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
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