我有一个可更改状态变量值的滑块:
onChange = (event, value) => {
this.setState({sliderValue: value,});
};
onDragEnd = (event, value) => {
this.props.fetchData(value);
};
...
<Slider
value={this.state.sliderValue}
min={0}
max={100}
step={1}
onChange={(event, value) => this.onChange(event, value)}
onDragEnd={(event) => this.onDragEnd(event)}
/>
有时,将setState用于 this.state.sliderValue 会花费一些时间,并且在触发this.props.fetchData(value)*之前,会先使用旧值进行数据提取。
我如何确保正在获取this.state.sliderValue的最后一个值?
答案 0 :(得分:1)
问题:
状态更新是异步任务。因此,当滑块更改其值时,您要更新sliderValue
,然后将状态sliderValue
设置为滑块以更新其值,但是当您停止拖动滑块和您的onDragEnd
回调函数会收到旧值通知。
解决方案:
在函数中,onDragEnd
仅标记必须检索数据。执行fetch
所需的值是状态,因此不需要滑块返回的值。
然后,您可以使用componentDidUpdate
来获取数据。
代码示例:
onChange = (event, value) => {
this.setState({sliderValue: value,});
};
componentDidUpdate(prevPros, prevState) {
// if data must be fetched and my slider value is updated (prev and current match)
if (this.state.fetchDataEnabled && prevState.sliderValue === this.state.sliderValue) {
this.props.fetchData(this.state.sliderValue);
this.setState({fetchDataEnabled: false});
}
}
<Slider
value={this.state.sliderValue}
min={0}
max={100}
step={1}
onChange={(event, value) => this.onChange(event, value)}
onDragEnd={() => this.setState({fetchDataEnabled: true})}
/>
答案 1 :(得分:0)
我终于可以使用RxJS debounceTime运算符解决问题了:
import {Subject} from "rxjs";
import {debounceTime} from 'rxjs/operators';
let onChange$ = new Subject();
...
componentDidMount() {
this.props.getWeightedCriteria(this.props.decisionId);
const subscription = onChange$
.pipe(
debounceTime(500)
)
.subscribe(
data => this.fetchSliderValues(data)
);
// prevent memory leaks
this.setState((prevState) => ({...prevState, subscription}));
}
componentWillUnmount() {
// prevent memory leaks
this.state.subscription.unsubscribe();
}
onChange = (event, value) => {
onChange$.next(value);
};
...
使用debounceTime运算符,将在500 ms内保持不变后获取值。然后,不再需要DragEnd方法。
在我有一些反应的经验之后,我了解到您永远不应该相信组件触发特定顺序的事件。