onsubmit gets triggered on every form field change - reactjs

I am trying to implement simple form which triggers API call on form submit in React.
It blows my mind as when trying the below code:
import React, { Component } from 'react';
import axios from 'axios';
var panelStyle = {
'max-width': '80%',
margin: '0 auto'
}
class DBInject extends Component {
constructor() {
super();
this.formHandler = this.formHandler.bind(this);
this.state = {
formFields: {Id: '',
Name: '',
Payment: "01-10-2019",
Type: '',
Value: 110,
Cycle:'',
Frequency:''
}
}
}
render() {
return(
<div>
<div class="panel panel-primary" style={panelStyle}>
<div class="panel panel-heading">React Forum - Register</div>
<div class="panel panel-body">
<form onsubmit={this.formHandler(this.state.formFields)}>
<strong>Id:</strong> <br /> <input type="text" name="Id" placeholder="123" onChange={(e) => this.inputChangeHandler.call(this, e)} value={this.state.formFields.Id} /> <br />
<strong>Name:</strong> <br /> <input type="text" name="Name" placeholder="me#example.com" onChange={(e) => this.inputChangeHandler.call(this, e)} value={this.state.formFields.Name}/> <br />
<strong>Cycle:</strong> <br /> <input type="text" name="Cycle" placeholder="me#example.com" onChange={(e) => this.inputChangeHandler.call(this, e)} value={this.state.formFields.Cycle} /> <br />
<strong>Frequency:</strong> <br /> <input type="text" name="Frequency" onChange={(e) => this.inputChangeHandler.call(this, e)} value={this.state.formFields.Frequency}/> <br />
<strong>Type:</strong> <br /> <input type="text" name="Type" onChange={(e) => this.inputChangeHandler.call(this, e)} value={this.state.formFields.Type} /> <br />
<strong>Payment:</strong> <br /> <input type="date" name="Payment" onChange={(e) => this.inputChangeHandler.call(this, e)} value={this.state.formFields.Payment}/> <br />
<strong>Value:</strong> <br /> <input type="number" name="Value" onChange={(e) => this.inputChangeHandler.call(this, e)} value={this.state.formFields.Value}/> <br /><br />
<button class="btn btn-primary">Send to database</button>
</form>
</div>
</div>
</div>
);
}
inputChangeHandler(e) {
console.log(e);
let formFields = {...this.state.formFields};
formFields[e.target.name] = e.target.value;
this.setState({
formFields
});
};
formHandler(formFields) {
console.log(formFields);
alert('This button does nothing.');
axios.post('http://127.0.0.1:1880/api','', {headers:formFields})
.then(function(response){
console.log(response);
//Perform action based on response
})
.catch(function(error){
console.log(error);
//Perform action based on error
});
}
}
export default DBInject
formHandler gets called every time InputchangeHandler gets called - which is not my intention.
Is there any other simpler way to do it in React?

Every time you call setState the component re-renders. Your form element is calling the function every time it re-renders. You need to make the following changes:
#Update onsubmit
<form onsubmit={this.formHandler.bind(this)}>
#Reference the formFields directly from the component's state
formHandler() {
const { formFields } = this.state;

You can read more on React forms here:
https://reactjs.org/docs/forms.html
Make sure to reference state from inside the handler function rather than passing it in - as this will make your function re-render every state update.
Form element:
//make sure the "S" in submit is capitalized
<form onSubmit={this.formHandler}>
...Your Form Contents
</form>
Handler function:
formHandler(e) {
e.preventDefault() // stop propagation at the start
// reference state from here with this.state like so:
const { formFields } = this.state;
...Your handler code
}

Related

using useState to change get the input:text and using onclick to print new <p>

i'm a beginner in React and trying to learn useState. and I have difficulties on how to get the value of input and to save the value and print it on button click
const HomePage = () => {
const [state, setState] = useState({
Name: "",
surName: "",
});
const handleChange = (e) => {
setState({
...state,
[e.target.name]: e.target.value,
});
};
const RenderNameOC = () => {
return (
<p>
Halo {Name} {surName}
</p>
);
};
return (
<DivContainer>
<ContainerTitle>
<p>Exercise 2 - Form</p>
</ContainerTitle>
<InputContainer>
<InputArea>
<label>Name: </label>
<input type="text" value={state.Name} onChange={handleChange} />
</InputArea>
<InputArea>
<label>Surname: </label>
<input type="text" value={state.surName} onChange={handleChange} />
</InputArea>
<SubmitButton onClick={RenderNameOC}>Submit</SubmitButton>
</InputContainer>
</DivContainer>
);
};
export default HomePage;
this is my code right now and the error it gave me was 'name' and 'surname' is not defined.
my expected result is that there will be 2 input textbox with for name and surname. and when the button is clicked, it will add a new <p> below it.
Here should be state.Name and state.surName
<p>
Halo {state.Name} {state.surName}
</p>
And add name in both inputs
<input
type="text"
name="Name"
value={state.Name}
onChange={handleChange}
/>
<label>Surname: </label>
<input
type="text"
name="surName"
value={state.surName}
onChange={handleChange}
/>
But no point of returning anything RenderNameOC since onClick is a void function. Just move this template below the submit button
Demo

How to display an unordered list into a JSX <ul> element in a React Form using class component

I'd like to write an unordered list compiled from a form's input values into a <ul> when I click on the Submit button. It's a controlled form in a class based component. Unfortunately I haven't found out how I can achieve it without hooks.
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
name: "",
email: "",
message: "",
demo: "",
};
this.changeHandler = this.changeHandler.bind(this);
this.submitFormHandler = this.submitFormHandler.bind(this);
}
changeHandler = (e) => {
this.setState = {
name: e.target.value,
email: e.target.value,
message: e.target.value,
demo: `
<li>${this.state.name}</li>
<li>${this.state.email}</li>
<li>${this.state.message}</li> `
};
this.setState(this.setState)
};
submitFormHandler = (e) => {
e.preventDefault();
// I guess the solution will be here somehow
};
render() {
return (
<form onSubmit={this.submitFormHandler} >
<label htmlFor="name">Name:</label> <br/>
<input id="name" type="text" value={this.state.name} onChange={this.changeHandler} />
<br/>
<label htmlFor="mail">E-mail:</label> <br/>
<input id="mail" type="email" value={this.state.email} onChange={this.changeHandler} />
<br/>
<label htmlFor="msg">Message:</label> <br/>
<textarea id="msg" type="email" value={this.state.message} onChange={this.changeHandler} />
<h4>Values of the inputs:</h4>
<ul id="demo">
{this.state.demo} {/* the list would be here! */}
</ul>
<button type="submit">Submit</button>
</form>
); }
};
To show something when it is submitted I would make a isSubmitted flag. Also you controlled inputs were not working. When inputs ids are corresponding with names in state we can easier handle them in onChange handler function. Also when it is submitted we can prevent user from updating data in changeHandler with early return. So I fixed it in code below:
// import React from 'react';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
name: '',
email: '',
message: '',
isSubmitted: false,
};
this.changeHandler = this.changeHandler.bind(this);
this.submitFormHandler = this.submitFormHandler.bind(this);
}
changeHandler = ({ target }) => {
if (this.state.isSubmitted) return;
this.setState({ [target.id]: target.value });
};
submitFormHandler = (e) => {
e.preventDefault();
this.setState({ isSubmitted: true });
};
render() {
return (
<div>
<form onSubmit={this.submitFormHandler}>
<label htmlFor="name">Name:</label> <br />
<input
id="name"
type="text"
value={this.state.name}
onChange={this.changeHandler}
/>
<br />
<label htmlFor="email">E-mail:</label> <br />
<input
id="email"
type="email"
value={this.state.email}
onChange={this.changeHandler}
/>
<br />
<label htmlFor="message">Message:</label> <br />
<textarea
id="message"
type="email"
value={this.state.message}
onChange={this.changeHandler}
/>
<br />
<button type="submit">Submit</button>
</form>
{this.state.isSubmitted && (
<React.Fragment>
<h4>Values of the inputs:</h4>
<ul>
<li>{this.state.name}</li>
<li>{this.state.email}</li>
<li>{this.state.message}</li>
</ul>
</React.Fragment>
)}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>

axios put request in react is returning empty

I'm pretty new with React and Call requests. I'm building a full stack app using React, express, MySql, and Sequelize.
Everything works fine except for the Put request to edit the client information. I'm using Axios to make those calls and I can add, see, and delete data from the app but the edit part is not working.
When hitting the submit button on the form, the Put request is returning an empty array instead of the actual modified data. My routes are Ok (I believe), as testing it with Postman work just fine. I'm almost sure that my problem is on the method being used in the axios call, but I can't just find the right way to make it work. Any help would be highly appreciated.
import React, { Component } from 'react';
import axios from 'axios';
import API from '../../utils/API';
class index extends Component {
constructor(props) {
super(props);
this.onChangeLastName = this.onChangeLastName.bind(this);
this.onChangeFirstName = this.onChangeFirstName.bind(this);
this.onChangePhone = this.onChangePhone.bind(this);
this.onChangePetName = this.onChangePetName.bind(this);
this.onChangeBreed = this.onChangeBreed.bind(this);
this.onChangeNotes = this.onChangeNotes.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.state = {
client: null
}
}
componentDidMount() {
let id = this.props.match.params.id
API.getClient(id)
.then(res => {
this.setState({
client: res.data
})
console.log(this.state.client.id)
})
.catch(error => console.log(error))
}
onChangeLastName(e) {
this.setState({
lastName: e.target.value
});
}
onChangeFirstName(e) {
this.setState({
firstName: e.target.value
});
}
onChangePhone(e) {
this.setState({
phone: e.target.value
});
}
onChangePetName(e) {
this.setState({
petName: e.target.value
});
}
onChangeBreed(e) {
this.setState({
breed: e.target.value
});
}
onChangeNotes(e) {
this.setState({
notes: e.target.value
});
}
onSubmit(e) {
e.preventDefault();
let obj = {
lastName: this.state.client.lastName.value,
firstName: this.state.client.firstName.value,
phone: this.state.client.phone.value,
petName: this.state.client.petName.value,
breed: this.state.client.breed.value,
notes: this.state.client.notes.value
};
let id = this.state.client.id
axios.put("http://localhost:3000/api/clients/" + id, obj)
// .then(alert("client Updated"))
.then(res => console.log(res))
.catch(error => console.log(error))
this.props.history.push('/admin');
}
render() {
const client = this.state.client ? (
<div className="client">
<h3 style={{ marginLeft: "60px" }}>Update Client</h3>
<form onSubmit={this.onSubmit} style={{ padding: "60px" }}>
<div className="form-group">
<label>Last Name: </label>
<input type="text"
className="form-control"
defaultValue={this.state.client.lastName}
onChange={this.onChangeLastName}
/>
</div>
<div className="form-group">
<label>First Name: </label>
<input type="text"
className="form-control"
defaultValue={this.state.client.firstName}
onChange={this.onChangeFirstName}
/>
</div>
<div className="form-group">
<label>Phone: </label>
<input type="text"
className="form-control"
defaultValue={this.state.client.phone}
onChange={this.onChangePhone}
/>
</div>
<div className="form-group">
<label>Pet Name: </label>
<input type="text"
className="form-control"
defaultValue={this.state.client.petName}
onChange={this.onChangePetName}
/>
</div>
<div className="form-group">
<label>Breed: </label>
<input type="text"
className="form-control"
defaultValue={this.state.client.breed}
onChange={this.onChangeBreed}
/>
</div>
<div className="form-group">
<label>Notes: </label>
<input type="text"
className="form-control"
defaultValue={this.state.client.notes}
onChange={this.onChangeNotes}
/>
</div>
<br />
<div className="form-group">
<input type="submit" value="Update Client"
className="btn btn-primary" />
</div>
</form>
</div>
) : (
<div className="center">Loading Client</div>
)
return (
<div className="container">
{client}
</div>
)
}
}
export default index;
I am assuming it is because of the way you are handling the onchange of your inputs. You want to set the onchange to the client value in your state. But instead you are setting it to the state itself. So then when you are building your object to send to the backend you are sending null data because you haven't set any data to the actual client value in your state and it is still null. Try console logging the state and you will see what I'm talking about. Also you are adding a .value to the end each of the state values you are trying to build your object with and this is not necessary. Finally you don't need to specify an onchange for each input just give the input a name attribute and you can set your onchange handler like so:
onChange = e => {
this.setState({
[e.target.name]: e.target.value
})
}
so your component would look something like the following:
import React, { Component } from 'react';
import axios from 'axios';
import API from '../../utils/API';
class index extends Component {
constructor(props) {
super(props);
this.onChange = this.onChange.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.state = {
client: null
}
}
componentDidMount() {
let id = this.props.match.params.id
API.getClient(id)
.then(res => {
this.setState({
client: res.data
})
console.log(this.state.client.id)
})
.catch(error => console.log(error))
}
onChange(e) {
this.setState({
client: {
...this.state.client,
[e.target.name]: e.target.value
}
});
}
onSubmit(e) {
e.preventDefault();
let obj = {
lastName: this.state.client.lastName,
firstName: this.state.client.firstName,
phone: this.state.client.phone,
petName: this.state.client.petName,
breed: this.state.client.breed,
notes: this.state.client.notes
};
let id = this.state.client.id
axios.put("http://localhost:3000/api/clients/" + id, obj)
// .then(alert("client Updated"))
.then(res => console.log(res))
.catch(error => console.log(error))
this.props.history.push('/admin');
}
render() {
const client = this.state.client ? (
<div className="client">
<h3 style={{ marginLeft: "60px" }}>Update Client</h3>
<form onSubmit={this.onSubmit} style={{ padding: "60px" }}>
<div className="form-group">
<label>Last Name: </label>
<input type="text"
name="lastName"
className="form-control"
defaultValue={this.state.client.lastName}
onChange={this.onChange}
/>
</div>
<div className="form-group">
<label>First Name: </label>
<input type="text"
name="firstName"
className="form-control"
defaultValue={this.state.client.firstName}
onChange={this.onChange}
/>
</div>
<div className="form-group">
<label>Phone: </label>
<input type="text"
name="phone"
className="form-control"
defaultValue={this.state.client.phone}
onChange={this.onChange}
/>
</div>
<div className="form-group">
<label>Pet Name: </label>
<input type="text"
name="petName"
className="form-control"
defaultValue={this.state.client.petName}
onChange={this.onChange}
/>
</div>
<div className="form-group">
<label>Breed: </label>
<input type="text"
name="breed"
className="form-control"
defaultValue={this.state.client.breed}
onChange={this.onChange}
/>
</div>
<div className="form-group">
<label>Notes: </label>
<input type="text"
name="notes"
className="form-control"
defaultValue={this.state.client.notes}
onChange={this.onChange}
/>
</div>
<br />
<div className="form-group">
<input type="submit" value="Update Client"
className="btn btn-primary" />
</div>
</form>
</div>
) : (
<div className="center">Loading Client</div>
)
return (
<div className="container">
{client}
</div>
)
}
}
export default index;
It could be because you're calling this.props.history.push immediately after calling axios.post, essentially redirecting before the POST request has a chance to return a response.
Try putting this.props.history.push('/admin') inside the .then().
You are doing multiple thing wrong here,
For every input you should have only 1 onChange handler, every input have name attribute to work with state. For example,
<input type="text"
className="form-control"
defaultValue={this.state.client.lastName}
name="lastName" //Like this should add name for every input like below
onChange={this.onChangeHandler} //This is a common onChangeHandler for every input should add in every input like below
/>
<input type="text"
className="form-control"
defaultValue={this.state.client.firstName}
name="firstName"
onChange={this.onChangeHandler}
/>
And onChangeHandler function should be,
onChangeHandler(e){
this.setState({
...this.state.client,
[e.target.name]:e.target.value
})
}
And finally your onSubmit function should be,
onSubmit(e) {
e.preventDefault();
let obj = {
lastName: this.state.client.lastName, //Remove `.value` as we are getting values from state and not directly from input
firstName: this.state.client.firstName,
phone: this.state.client.phone,
petName: this.state.client.petName,
breed: this.state.client.breed,
notes: this.state.client.notes
};
let id = this.state.client.id
axios.put("http://localhost:3000/api/clients/" + id, obj)
// .then(alert("client Updated"))
.then(res => console.log(res))
.catch(error => console.log(error))
this.props.history.push('/admin');
}
Note: You won't get value here in console.log,
API.getClient(id)
.then(res => {
this.setState({
client: res.data
})
console.log(this.state.client.id)
})
beacuse seState is async, you should use callback in setState to make console.log,
API.getClient(id)
.then(res => {
this.setState({
client: res.data
}, () => console.log(this.state.client.id)) //This is callback
})

React - Input fields not editable even after I set the state

I am trying to type on the inputs but it is not allowing me too. My state changes but it doesn't show.
I am using props to show an event OR and empty event if there is no props (no event selected).
Im sorry but Stack is telling me to add more details but I don't know what else to add, I already described my problem
class EventForm extends PureComponent {
state = {
event: this.props.selectedEvt,
query: ""
};
onFormSubmit = e => {
e.preventDefault();
this.props.addEvent(this.state.event);
};
onInputChange = evt => {
console.log(evt);
evt.persist();
let newEvt = this.state.event;
newEvt[evt.target.name] = evt.target.value;
this.setState({
event: newEvt
});
};
componentDidUpdate(prevProps) {
this.props.selectedEvt &&
this.setState({
event: this.props.selectedEvt
});
}
render() {
const { event } = this.state;
return (
<form className="card" onSubmit={this.onFormSubmit}>
<div className="form-row card-body">
<div className="form-group col-md-12">
<label hmtlfor="inputName">Event Name</label>
<input
name="title"
type="text"
className="form-control"
id="inputEventName"
onChange={this.onInputChange}
value={event.title}
/>
<label hmtlfor="inputDate">Event Date</label>
<input
name="date"
type="date"
className="form-control"
id="inputEventDate"
onChange={this.onInputChange}
value={event.date}
/>
<label hmtlfor="inputDate">Event Time</label>
<input
name="time"
type="time"
className="form-control"
id="inputEventTime"
onChange={this.onInputChange}
value={event.time}
/>
<label hmtlfor="inputAddress">Address</label>
<input
name="address"
type="text"
className="form-control"
id="autocomplete"
onChange={this.onInputChange}
value={event.address}
autoComplete="new-password"
/>
<label hmtlfor="inputHost">Hosted By</label>
<input
name="host"
type="text"
className="form-control"
id="inputHost"
onChange={this.onInputChange}
value={event.host}
/>
<label hmtlfor="inputDesc">Description</label>
<textarea
name="desc"
className="form-control"
rows="5"
id="inputDesc"
wrap="soft"
onChange={this.onInputChange}
value={event.description}
/>
<button type="submit" className="btn btn-primary mt-2">
Submit
</button>
</div>
</div>
</form>
);
}
}
export default EventForm;
Every time input value change componentDidMount run and you reset state to initial state value in componentDidUpdate.
componentDidUpdate(prevProps) {
this.props.selectedEvt &&
this.setState({
event: this.props.selectedEvt // Here is the problem
});
}
Also You mutate state when input change. And because its pureComponent it will not update.
Change onInputChange to
onInputChange = evt => {
let name = evt.target.name;
let value = evt.target.value;
let newEvent = {...this.state.event};
newEvent[name] = value
this.setState({event: newEvent});
}

ReactJS Uncaught ReferenceError: onSubmit is not defined

Please help me to understand where I am doing what mistake? I created CustomerForm React Component, which having few form fields. These form fields will add records and in another component will show records into table format.
Every thing is working fine for CustomerForm React Component, but if I am adding onSubmit function than form fields are not loading and I am getting console error as:-
Uncaught ReferenceError: onSubmit is not defined
at new CustomerForm (index.js:32590)
<button type="submit" className="btn btn-primary" onClick={ e => this.onSubmit(e)} > Submit </button>
Also please suggest any better way to write ReactJS code using Props & State...
// Let's import react for creating component
import React from "react";
// Create CustomerForm component
class CustomerForm extends React.Component{
// create constructor function for CustomerForm component
constructor(props){
// call super, so constructor function can connect with CustomerForm component
super(props);
// Use state add object with their property and value
this.state = {
firstName : "",
lastName : "",
phoneNo : "",
issue : "",
}
// Create changeData function
// changeData = e => {
// this.setState({
// [e.target.name] : e.target.value
// });
// };
onSubmit = e => {
e.preventDefault();
console.log(this.state);
}
} // close constructor function
render(){
return(
<form>
<div className="form-group">
<label htmlFor="fname">First name</label>
<input
type="text"
className="form-control"
id="fname"
placeholder="First name"
value={this.state.firstName}
onChange={e => this.setState({ firstName: e.target.value })}
/>
{/* call setState for change firstName value
question - I created changeData function which target name attribute and change value for form fields, but it's not working
onChange={e => this.changeData(e)}
*/}
</div>
<div className="form-group">
<label htmlFor="lname">Last name</label>
<input
type="text"
className="form-control"
id="lname"
placeholder="Last name"
value={this.state.lastName}
onChange={e => this.setState({ lastName: e.target.value })}
/>
{/* call setState for change lastName value */}
</div>
<div className="form-group">
<label htmlFor="phone">Phone no.</label>
<input
type="text"
className="form-control"
id="phone"
placeholder="Phone no."
value={this.state.phoneNo}
onChange={e => this.setState({phoneNo: e.target.value})}
/>
{/* call setState for change phoneNo value */}
</div>
<div className="form-group">
<label htmlFor="issue">Issue</label>
<textarea
className="form-control"
id="issue"
rows="3"
value={this.state.issue}
onChange={e => this.setState({issue: e.target.value})}
>
{/* call setState for change issue value */}
</textarea>
</div>
<button
type="submit"
className="btn btn-primary"
onClick={ e => this.onSubmit(e)}
>
Submit
</button>
</form>
);
}
}
export default CustomerForm;
You're declaring a variable named onSubmit on the constructor and trying to access it with this.onSubmit, like a property.
You can do this in your constructor:
this.onSubmit = e => {
e.preventDefault();
console.log(this.state);
}
The suggestion
A better way to accomplish this is extracting your onSubmit method to a class method, with makes your code more readable and more consistent. Would be something like this:
// Let's import react for creating component
import React from "react";
// Create CustomerForm component
class CustomerForm extends React.Component{
// create constructor function for CustomerForm component
constructor(props){
// call super, so constructor function can connect with CustomerForm component
super(props);
// Use state add object with their property and value
this.state = {
firstName : "",
lastName : "",
phoneNo : "",
issue : "",
}
}
/////////
/// Your submit handler is now a method in the CustomerForm class,
/// so you can access with the keyword "this"
onSubmit(e) {
e.preventDefault();
console.log(this.state);
}
render(){
return(
<form onSubmit={e => this.onSubmit(e)}>
{/* Note that I've changed your handler to form,
is usually better than put on a button, since you're using a form already */}
<div className="form-group">
<label htmlFor="fname">First name</label>
<input
type="text"
className="form-control"
id="fname"
placeholder="First name"
value={this.state.firstName}
onChange={e => this.setState({ firstName: e.target.value })}
/>
{/* call setState for change firstName value
question - I created changeData function which target name attribute and change value for form fields, but it's not working
onChange={e => this.changeData(e)}
*/}
</div>
<div className="form-group">
<label htmlFor="lname">Last name</label>
<input
type="text"
className="form-control"
id="lname"
placeholder="Last name"
value={this.state.lastName}
onChange={e => this.setState({ lastName: e.target.value })}
/>
{/* call setState for change lastName value */}
</div>
<div className="form-group">
<label htmlFor="phone">Phone no.</label>
<input
type="text"
className="form-control"
id="phone"
placeholder="Phone no."
value={this.state.phoneNo}
onChange={e => this.setState({phoneNo: e.target.value})}
/>
{/* call setState for change phoneNo value */}
</div>
<div className="form-group">
<label htmlFor="issue">Issue</label>
<textarea
className="form-control"
id="issue"
rows="3"
value={this.state.issue}
onChange={e => this.setState({issue: e.target.value})}
>
{/* call setState for change issue value */}
</textarea>
</div>
<button
type="submit"
className="btn btn-primary"
>
Submit
</button>
</form>
);
}
}
export default CustomerForm;
Controlled Components
Just one more thing I think it may be helpful to you (I've noted your comment about changeData) so if you not resolve the way to do controlled inputs, this minimalist example may help you, with a onChangeHandler I usually use:
import React from 'react';
export default class MyControlledComponent extends React.Component {
constructor(props){
super(props);
// Initiating the first value for our controlled component
this.state = {
name: ""
}
}
submitHandler(e) {
e.preventDefault();
console.log('Hi, ' + this.state.name + '!');
}
onChangeHandler(e) {
const { name, value } = e.target
/*
Here we using the name property of your input to
increase reuse of this function
*/
this.setState({
[name]: value
});
}
render(){
return (
<div className="my-app">
<form onSubmit={e => this.submitHandler(e)}>
<input type="text"
name="name"
value={this.state.name}
onChange={e => this.onChangeHandler(e)} />
<button>Send!</button>
</form>
</div>
)
}
}
Hope it helps!
Your onSubmit function is not bind either bind it in constructor or use fat arrow properly like
{(return)=>{functionname()}}

Resources