我有一个DatePicker组件,当我点击一个新的日期时,它应该在redux商店中设置更改日期,并且还明显地看待UX。
我会将我的代码放在下面,由于handleChange
函数中的某些原因,setState
和this.props.addFitler
都关闭,redux存储更新正确但是用户体验没有。
但是,如果我注释掉this.props.addFilter
调度功能,那么UX更新正确(显然商店没有)。
为什么这两个都不能一起工作?我已经尝试改变它们被调用的顺序,将每个函数提取到另一个函数中,使用mapDispatchToProps而不是直接调用动作创建器,但都无济于事。
DatePicker.js:
import DatePicker from 'react-datepicker';
class DatePick extends React.Component {
constructor(props) {
super(props);
this.state = {
date: moment()
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(date) {
const { dashboardName } = this.props;
const { name } = this.props.column;
this.props.addFilter(date, dashboardName, name);
this.setState({date});
}
render() {
return (
<div style={{display: 'inline-block', fontWeight: 'bold'}}>
<DatePicker
dateFormat="DD/MM/YYYY"
selected={this.state.date}
onChange={this.handleChange} />
</div>
);
}
}
const mapActionToProps = {
addFilter
};
export default connect(null, mapActionToProps)(DatePick);
handleChange函数中出现的'date'参数是一个时刻对象,就像用于设置initialState的那个一样,所以这不是问题。
附加信息:如果我在setState()
之前和之后控制日志,它会同时记录初始状态。
是否有人遇到此问题或有任何想法?如果您需要查看我的redux,我可以使用更多代码更新帖子,但我不认为这是问题,因为它更新了商店。
答案 0 :(得分:1)
我找到了解决方案,动作创建者调用正在进行一些同步操作,整个UI线程被锁定,直到它完成它所做的任何事情。因此,我们可以在setTimeout的帮助下稍微延迟调用,一切都会按预期进行
答案 1 :(得分:0)
我不认为setTimeout
是上一个答案中所建议的很好的解决方案。我们无法确定操作创建者花费的实际时间(因为它可能包含异步调用,例如API调用)。这将再次导致缺少setState渲染的原始问题。再次设置较长的超时将是不好的做法。您的申请将有不必要的延迟。
一种可能的解决方案是使用setState
的回调方法来触发动作创建者。
handleChange(date) {
const { dashboardName } = this.props;
const { name } = this.props.column;
this.setState({date}, () => {
this.props.addFilter(date, dashboardName, name);
});
}
在这种情况下,setState
渲染完成后将触发动作创建者。
其他解决方案是在收到新道具时使用反应生命周期方法来运行setState
。
这样,在动作创建者退回道具并更改状态之后,setState
被触发。
componentWillRecieveProps (nextProps) {
// check the related prop is changed
// setState
}
但是使用react 17时,此方法将很快被弃用。以下是新的稳定替代品。 https://hackernoon.com/problematic-react-lifecycle-methods-are-going-away-in-react-17-4216acc7d58b
static getDerivedStateFromProps(nextProps, prevState) {
// check the related prop is changed
// setState
}