onChange event updates state with 1 character delay
What helped me in this case was finding out that setState has a callback function, i.e
this.setState({ someState: 'someState' }, () => {
//Anything you need to do after state update here
});
onChange is one character on delay - Hooks
As you know, useState is async function. When you use useState inside functional Component, you have to handle variable in useEffect to see change of variable like this:
const App = () => {
const [search, setSearch] = useState("");
const onChange = e => {
e.persist();
setSearch(e.target.value);
};
useEffect(() => {
console.log("Search message inside useEffect: ", search);
}, [search]);
return <input onChange={onChange} />;
};
update state with onchange event have a delay character
setState()
does not immediately mutate this.state
but creates a pending state transition. Accessing this.state
after calling this method can potentially return the existing value.
See more about it https://facebook.github.io/react/docs/component-api.html
Changing state for input is delayed by one character (useState hook)
it's always one character late
The console logs are within the previous state cycle so it's expected that it's "one cycle" late. Remember setState()
is asynchronous.
If you want to log the current changes, use useEffect
hook.
useEffect(() => {
console.log(filteredData.query); // not late
console.log(filteredData.filteredProfiles); // same here!
}, [filteredData]);
The effect hook will listen for current filteredData
changes and log it.
Also I suggest using useCallback
for event handlers.
Delay on updating the state by one character
In your updateInputField
function - Instead of calculating the sum
before updating input[key]
, try updating updating input[key]
, then calculate sum
. Like this:
// first, update 'input' with the new value
input[key] = value;
// next, calculate the new sum
let sum = +input.inputField1 + +input.inputField2 + +input.inputField3 + +input.inputField4
The "Delay" you're seeing is due to the fact that your code follows this order:
- Gets old
input
values from state - Calculates the sum of the old
input
values - Updates
input
(at the currentkey
that got updated) with thevalue
- This needs to be #2, not #3!
- Sets the updated
input
in state - Calls
this.updateInput
So your new updateInputField
function would look like this:
updateInputField= (key, value) => {
let {input} = this.state;
// first, update 'input' with the new value
input[key] = value;
// next, calculate the new sum
let sum = +input.inputField1 + +input.inputField2 + +input.inputField3 + +input.inputField4
this.setState({input});
window.input = input;
this.updateInput("amount",sum)
};
onChange input delay in React
Since State Updates May Be Asynchronous.
With hooks, this can be achieved by
const [state, setState] = useState(/* ... */)
setState(/* ... */)
useEffect(() => {
// state is guaranteed to be what you want
}, [state])
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.
Related Topics
How to Tell If a Dom Element Is Visible in the Current Viewport
Why Am I Not Able to Add Input Text into My Table
How to Convert Seconds to Minutes and Hours in JavaScript
How to Set the Multi Sliders in One Page
Change Td Background Colour Based on the Value
Sequlize Order by Only from Main Query
Form Builder - Cannot Read Property 'Get' of Undefined, Issue With Validators
Javascript Random on Array Without Repeat
Input Quantity Button Plus and Minus
Prevent Sweetalert to Be Closed on Clicking Outside the Popup Window
How to Remove Image from Browser Cache
Convert Hex to Binary in JavaScript
Uncaught Referenceerror: (Function) Is Not Defined At
How to Translate the Following Jquery Code to React
Onclick Event Function in JavaScript