onChange in React doesn't capture the last character of text
When are you logging the state? Remember that setState
is asynchronous, so if you want to print the new state, you have to use the callback parameter. Imagine this component:
let Comp = React.createClass({
getInitialState() {
return { text: "abc" };
},
render() {
return (
<div>
<input type="text" value={this.state.text}
onChange={this.handleChange} />
<button onClick={this.printValue}>Print Value</button>
</div>
);
},
handleChange(event) {
console.log("Value from event:", event.target.value);
this.setState({
text: event.target.value
}, () => {
console.log("New state in ASYNC callback:", this.state.text);
});
console.log("New state DIRECTLY after setState:", this.state.text);
},
printValue() {
console.log("Current value:", this.state.text);
}
});
Typing a d
at the end of the input will result in the following being logged to the console:
Value from event: abcd
New state DIRECTLY after setState: abc
New state in ASYNC callback: abcd
Notice that the middle value is missing the last character. Here's a working example.
Since setState() function in asynchronous, I used await.I achieved this using async and await, here is my code
render: function() {
return <div className="input-group search-box">
<input
onChange={(e) => {this.handleTextChange(e)}}
type="text"
value={this.state.text}
className="form-control search-item" />
<span className="input-group-btn"></span>
</div>
}
The handleTextCahnge function:
handleTextChange = async function(event) {
await this.setState({text: event.target.value});
console.log(this.state.text);
}
Since React v.16.8 react hooks can be helpful. I would recommend useState AND useEffect. The Example is in React Native, however it should show how to work with the useEffect. More information about useEffect: https://reactjs.org/docs/hooks-effect.html
import React, {useState, useEffect} from 'react';
import { TextInput } from 'react-native';
export interface Props{}
const InformationInputs: React.FC<Props> = (props) => {
const [textInputs, setTextInputs] = useState("");
const handleValueChange = () => {
console.log(textInputs);
}
useEffect(() => {
handleValueChange();
}, [textInputs]);
return (
<TextInput
placeholder={'Text'}
onChangeText={(value: string) => { setTextInputs(value) }}
/>
);
};