I am trying to create a custom number picker component and trying to add it to the components wherever it is needed. But When I am trying to fetch the number picker value in the Parent component , I am getting the older value . Can someone help me with this?
import * as React from "react";
interface IState {
value: number;
}
interface IProps {
setValue(val: number): void;
}
class NumberPicker extends React.Component<IProps, IState> {
constructor(props: any) {
super(props);
this.state = {
value: 0
};
}
public doDecrement = () =>
// DECREMENT CODE
{
if (this.state.value < 1) {
console.log("LESS THAN O");
} else {
this.setState({
value: this.state.value - 1
});
this.props.setValue(this.state.value);
}
};
public doIncrement = () =>
// INCREMENT CODE
{
this.setState({
value: this.state.value + 1
});
this.props.setValue(this.state.value);
};
public handleChange = (
e: React.ChangeEvent<HTMLInputElement> // CHANGE HANDLER
) => {
const val = parseInt(e.target.value);
this.setState({ value: val });
};
public render() {
return (
<div>
<button
onClick={this.doDecrement}
className="fa fa-minus fa-inverse fa-2x"
/>
<input
type="text"
className="number"
value={this.state.value}
onChange={this.handleChange}
/>
<button
onClick={this.doIncrement}
className="fa fa-plus fa-inverse fa-2x"
/>
</div>
);
}
}
export default NumberPicker;
import * as React from "react";
import NumberPicker from "./NumberPicker";
interface IState {
val: number;
}
interface IProps {}
class Parent extends React.Component<IProps, IState> {
constructor(props: any) {
super(props);
this.state = {
val: 0
};
}
handleVal = (value: number) => {
this.setState({ val: value }, () => console.log(this.state.val));
};
render() {
return (
//Some fields along with the below numberpicker
<NumberPicker setValue={this.handleVal} />
);
}
}
export default Parent;
I have tried using setState's callback function as well, but it does not seem to be working . Parent component always shows the older value.How will I get the updated value of the NumberPicker inside parent? Help would be appreciated!
React's setState
is asynchronous, and because of that this.props.setValue
function is going to be called before setState
has updated your state in child Numberpicker component. This is why an old value is passed to the parent component.
Instead you can call this.props.setValue
inside setState
's callback function.
public doIncrement = () =>
// INCREMENT CODE
{
this.setState({
value: this.state.value + 1
}, () => {
this.props.setValue(this.state.value);
});
};
public doDecrement = () =>
// DECREMENT CODE
{
if (this.state.value < 1) {
console.log("LESS THAN O");
} else {
this.setState({
value: this.state.value - 1
}, () => {
this.props.setValue(this.state.value);
});
}
};
setState is not a synchrounous function. So when you are calling the callback from parent you are calling it with old state value, because new value will be set sometime in future. You can call the callback with the same value you are setting to state: this.state.value - 1 or this.state.value + 1. It should work as expected. I also recommend to read thinking in react for better intuition about where you should hold your state.
Don't use state for passing values in callback, you can do like:-
handleChange = (
e: React.ChangeEvent<HTMLInputElement> // CHANGE HANDLER
) => {
const val = parseInt(e.target.value);
// this.setState({ value: val });
this.props.setValue(val);
};
i hope it helps!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.