How to attach One Event Handler to different Inputs in React JS? - reactjs

I am new to react js.
I have several inputs in my form and considering controllable input approach in React , I am trying to do the job with one event handler to every other inputs. I took some references in stack overflow and come to this. Still not able to figure it out why I am unable to write inside my input box.
Here is my code.
import React, {Component} from 'react';
import { Grid, Row, Col , Button } from 'react-bootstrap';
class ContactForm extends Component {
constructor(props) {
super(props);
this.state = {
name: '' ,
email: ''
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
this.setState({[e.target.name]: e.target.value})
}
render() {
return (
<form>
<input name="input1" value={this.state.name} onChange={this.handleChange}/>
<input name="input2" value={this.state.email} onChange={this.handleChange} />
<p>{this.state.name}, {this.state.email}</p>
</form>
);
}
}
export default ContactForm;

You're using the name attribute to identify the input, but you're reading the wrong values in the render function, "name" and "email" instead of "input1" and "input2"
You can do this instead:
<input name="input1" value={this.state.input1} onChange={this.handleChange}/>
<input name="input2" value={this.state.input2} onChange={this.handleChange} />
or
<input name="name" value={this.state.name} onChange={this.handleChange}/>
<input name="email" value={this.state.email} onChange={this.handleChange} />
You'd also have to change this :
this.state = {
name: '' ,
email: ''
};
in the constructor if you're using the first option.

I would use ref to achieve this:
handleChange(e) {
const {input1, input2} = this.refs;
//do what ever you want with the values
}
render() {
return (
<form>
<input name="input1" value={this.state.name} ref="input1" />
<input name="input2" value={this.state.email} ref="input2" onChange={this.handleChange} />
<p>{this.state.name}, {this.state.email}</p>
</form>
);
}
}
Also, I would use a submit button, or something like that, instead of an event listener on one or two of the inputs

Related

Keep getting max update exceeded error but cannot seem to find error in code

I have made forms like this before but I seem to be missing something in this one. I keep getting the error "maximum update depth exceeded error" but I dont see where I am goin wrong and I've spent too much time looking at it. I already tried to change my onChange to include an arrow because others have suggested to do so , but when that happens I cant type in the input boxes. like so
onChange={()=>this.handleChange("username")}
I should note that I only get the error when I try to register the user and not when I type into the input. Here is the full error as well.
at checkForNestedUpdates (react-dom.development.js:23804)
at scheduleUpdateOnFiber (react-dom.development.js:21836)
at Object.enqueueSetState (react-dom.development.js:12468)
at Router.Component.setState (react.development.js:366)
at react-router.js:75
at listener (history.js:156)
at history.js:174
at Array.forEach (<anonymous>)
at Object.notifyListeners (history.js:173)
at setState (history.js:562)
Here is my code, please help.
import React from "React"
class Splash extends React.Component{
constructor(props) {
super(props)
this.state = this.props.user;
this.handleSubmit = this.handleSubmit.bind(this);
}
componentDidMount() {
this.props.clearErrors();
}
handleSubmit(event) {
event.preventDefault();
this.props.signUp(this.state);
}
handleChange(field) {
return (e) => {
this.setState({ [field]: e.currentTarget.value })
};
}
render() {
return (
<div className="splash-background">
<div className="modal-screeen">
<form className="modal" onSubmit={this.handleSubmit}>
<h2 className="welcom-text"></h2>
<input className="user-input" type="text" placeholder="Name" onChange={this.handleChange("name")} value={this.state.name}/>
<input className="user-input" type="text" placeholder="Email" onChange={this.handleChange("email")} value={this.state.email}/>
<input className="user-input" type="text" placeholder="Create Username" onChange={this.handleChange("username")} value={this.state.username}/>
<input className="user-input" type="password" placeholder="Create Password" onChange={this.handleChange("password")} value={this.state.password}/>
<button>Sign Up</button>
</form>
</div>
</div>
);
}
}
export default Splash
import { connect } from "react-redux";
import { signup, login, clearErrors } from "../../actions/session_actions.js";
import Splash from "./splash";
const mapStateToProps = ({ errors }) => {
return {
errors: errors.session,
user: {
username: "",
password: "",
name:"",
email: "",
},
};
};
const mapDispatchToProps = (dispatch) => {
return {
signUp: (user) => dispatch(signup(user)),
login: (user) => dispatch(login(user)),
clearErrors: () => dispatch(clearErrors()),
};
};
export default connect(mapStateToProps, mapDispatchToProps)(Splash);
I believe the problem here is the implementation of redux and react state. If you're using redux to manage the form state then I don't think there is a need to also manage that same state with react.
Try something like this, but keep in mind this code isn't tested.
class Splash extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
}
componentDidMount() {
this.props.clearErrors();
}
handleSubmit(event) {
event.preventDefault();
this.props.signUp(this.props.user);
}
handleChange(e) {
// here you would have another action to update redux state depending
// on which input has changed. You can grab the input name via e.target.name
}
render() {
return (
<div className="splash-background">
<div className="modal-screeen">
<form className="modal" onSubmit={this.handleSubmit}>
<h2 className="welcom-text"></h2>
<input
className="user-input"
type="text"
placeholder="Name"
name="name"
onChange={this.handleChange}
value={this.props.user.name}
/>
<input
className="user-input"
type="text"
placeholder="Email"
name="email"
onChange={this.handleChange}
value={this.props.user.email}
/>
<input
className="user-input"
type="text"
placeholder="Create Username"
name="username"
onChange={this.handleChange}
value={this.props.user.username}
/>
<input
className="user-input"
type="password"
placeholder="Create Password"
name="password"
onChange={this.handleChange}
value={this.props.user.password}
/>
<button>Sign Up</button>
</form>
</div>
</div>
);
}
}
export default Splash;
When it comes to form data, I find it's easier to manage just with react state. Generally redux is used to manage state that is shared across the whole application/multiple components.
The problem was actually in my route util file. I had an infinite loop of rerouting!

REACTJS: value is not defined

I have three states which consists of name, age and email which its values are manually specficied in order to display the values in the three input text fields.
However, I want to make all of the three values from the input text field editable as well.
I'm receving an error age is not defined. May I know why?
Here is the link which used to run the code below:
https://stackblitz.com/edit/react-zyeeed
import React, { Component } from 'react';
import { render } from 'react-dom';
class Info extends Component {
constructor(props) {
super(props);
state = {
name = "Jack Sparrow",
age = "52",
email = "jacksparrow52#gmail.com"
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
let newState = {...this.state};
newState[e.target.name] = e.target.name
this.setState({
newState
})
}
render() {
return (
<div>
<input type="text" name="name" value={this.state.name} placeholder="Enter your name..." onChange={(e) => this.handleChange(e)} />
<br /> <br />
<input type="text" name="age" value={this.state.age} placeholder="Enter your age..." onChange={(e) => this.handleChange(e)} />
<br /> <br />
<input type="text" name="email" value={this.state.email} placeholder="Enter your email..." onChange={(e) => this.handleChange(e)} />
<h3>Output states:</h3>
<p id="name">Entered Name: {this.state.name}</p>
<p id="age">Entered Age: {this.state.age}</p>
<p id="age">Entered Email: {this.state.email}</p>
</div>
);
}
}
render(<Info />, document.getElementById('root'));
There are a few things missing.
Need to use this.state
Correct the assignment of state properties
Change newState[e.target.name] = e.target.name to newState[e.target.name] = e.target.value
Change this.setState({ newState }) to this.setState(newState) or this.setState({ ...newState })
I think that covers it. I made a working example. Hope that helps!
Missing a this
this.state = {
name = "Jack Sparrow",
age = "52",
email = "jacksparrow52#gmail.com"
};

How to show the input field value in another input field using reactjs?

I'm new to reactjs. I'm bit confused how to do it, i want to write something in first input field and at the same time it should reflect on the second input field. If i delete the value in the first input field then it should delete the second input field also. Can anybody help me in this?
Here is the Code:
import React, { Component } from "react";
import "./styles.css";
import { Form, Input, Button } from "semantic-ui-react";
class App extends Component {
constructor() {
super();
this.state = {
name: "",
email: ""
};
}
handleName = event => {
this.setState({ [event.target.name]: event.target.value });
};
render() {
return (
<div className="App">
<Form>
<Input
placeholder="Name"
onChange={this.handleName}
name="name"
value={this.state.name}
/>
<Input
placeholder="Email"
onChange={this.handleName}
name="email"
value="#yahoo.com"
/>
</Form>
<Button>Submit</Button>
</div>
);
}
}
export default App;
code: "https://codesandbox.io/s/reverent-fast-3w8sz"
You need to use same {this.state.name} as a value for both field. for example:
<Input
placeholder="Name"
onChange={this.handleName}
name="name"
value={this.state.name}
/>
<Input
placeholder="Email"
onChange={this.handleName}
name="email"
value={this.state.name}
/>
If you want to keep yahoo.com as suffix with the in the second input replace the value prop of the input field with value={`${this.state.name}yahoo.com`}. Hope this is what you are looking for

React how to set a default value

Hello I'm new to react and redux. What I'm trying to do is have an edit page that gets the value from my server and puts it in an input value so the user can edit the value.
<FormGroup>
<Label htmlFor="name">Name *</Label>
<div className="controls">
<InputGroup>
<Input id="name" size="16" type="text" value={this.props.user.name} />
</InputGroup>
</div>
</FormGroup>
Inside a react component.
constructor(props) {
super(props)
this.handleSubmit = this.handleSubmit.bind(this)
this.componentWillMount = this.componentWillMount.bind(this)
}
componentWillMount(){
// this will return my current user
this.props.dispatch(fetchUser())
console.log(this.props.user.name) //outputs 'John'
}
How can i insert the username inside the input. I tried using the id and all the traditional javascript ways but its not working.
It looks like used a react-bootstrap.
Below sample use defaultValue property.
if you want to handle input value by
<FormControl
type="text"
autoFocus
onBlur={this.handleMessage}
defaultValue={this.props.user.name}
/>
handlers...
handleMessage = (event) => {
this.setState({
userName: event.target.value,
});
// or do action
// this.props.dispatch(notifyAction.changeUserName(event.target.value));
};

Submitting redux form values

I am new to react and redux technology. now started building an application that contains several redux forms. We want to submit simple form with values.
For ex: login form
Username : text input field
Password: text input field
Submit button
After entering values in fields and click on submit button i want to get the username and password field values in object or json data .. so that I can store it to my server with POST method.
Right now we are using handleSubmit(), but data is not coming as object
1 - The best practice to deal with input values are making them controlled. Which means :
Instead of
<input type='password' />
You do :
<input
type='password'
value={password}
onChange={ event => myInputHandler( event.target.value ) }
/>
The value might come from your state, redux state or as a props etc.
Your handler function differs according to where you store it.
I will give you an example with react state :
<input
type='password'
value={this.state.password}
onChange={ event => this.setState({ password : event.target.value }) }
/>
So whenever someone types, your onChange handler will be called, so that your react state will update with the input ( event.target.value ).
2 - If you need these values when a user submits, then you need to wrap these input fields within a form element and attach a onSubmit handler.
onSubmitHandler( event ){
event.preventDefault()
let password = this.state.password
// use password or other input fields, send to server etc.
}
<form onSubmit={ event => this.onSubmitHandler(event) }>
<input
type='password'
value={this.state.password}
onChange={ event => this.setState({ password : event.target.value }) }
/>
</form>
Hope you get what you need.
If you are using redux to store state then use redux-from then use redux from
import React from 'react'
import {Field, reduxForm} from 'redux-form'
const SimpleForm = props => {
const {handleSubmit, submitting} = props return (
<form onSubmit={handleSubmit(e=>console.log('your form detail here', e))}>
<div>
<label>First Name</label>
<div>
<Field name="firstName" component="input" type="text" placeholder="First Name" />
</div>
</div>
<div>
<label>Last Name</label>
<div>
<Field name="lastName" component="input" type="text" placeholder="Last Name" />
</div>
</div>
<div>
<button type="submit" disabled={pristine || submitting}>Submit</button>
</div>
</form>
) }
export default reduxForm({ form: 'simple'})(SimpleForm)
Go here for more detail
https://redux-form.com
I put the name of the input as the key that I want to use.
Then each time the input changes I destructure the event passed to the onChange function, and I use the name,value to update the state.
On form submit make sure to use preventDefault(); in order to avoid the page refreshing.
import React, { Component } from 'react'
class FormExample extends Component {
constructor(props){
super(props)
this.state = {
formData: {}
}
}
handleInputChange = ({ target: { name,value } }) => {
this.setState({
formData: {
...this.state.formData,
[name]: value
}
})
}
handleFormSubmit = e => {
e.preventDefault()
// This is your object
console.log(this.state.formData)
}
render() {
return(
<div>
<Form
handleSubmit={this.handleFormSubmit}
handleChange={this.handleInputChange}
/>
</div>
)
}
}
const Form = ({ handleSubmit, handleChange }) => (
<form onSubmit={handleSubmit}>
<input onChange={handleChange} name="username" type="text" placeholder="Username" />
<input onChange={handleChange} name="password" type="password" placeholder="Password" />
<button>Submit</button>
</form>
)
export default FormExample

Resources