Javascript Dispatch和setState不一起工作,但各自独立

Javascript Dispatch和setState不一起工作,但各自独立,javascript,reactjs,redux,Javascript,Reactjs,Redux,我有一个DatePicker组件,当我点击一个新的日期时,它应该在redux存储中设置更改日期,并且可以看到UX智能 出于某种原因,我将把我的代码放在下面的handleChange函数中,在setState和this.props.addFitler同时启动时,redux存储会正确更新,但UX不会。 但是,如果我注释掉this.props.addFilterdispatch函数,UX将正确更新(很明显,商店不会) 为什么这两个不一起工作?我尝试过改变调用它们的顺序,将它们提取到另一个函数中,使用m

我有一个DatePicker组件,当我点击一个新的日期时,它应该在redux存储中设置更改日期,并且可以看到UX智能

出于某种原因,我将把我的代码放在下面的
handleChange
函数中,在
setState
this.props.addFitler
同时启动时,redux存储会正确更新,但UX不会。 但是,如果我注释掉
this.props.addFilter
dispatch函数,UX将正确更新(很明显,商店不会)

为什么这两个不一起工作?我尝试过改变调用它们的顺序,将它们提取到另一个函数中,使用mapDispatchToProps而不是直接调用action creator,但都没有效果

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);
从'react DatePicker'导入日期选择器;
类DatePick扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
日期:矩()
};
this.handleChange=this.handleChange.bind(this);
}
手册更改(日期){
const{dashboardName}=this.props;
const{name}=this.props.column;
this.props.addFilter(日期、仪表板名称、名称);
this.setState({date});
}
render(){
返回(
);
}
}
常量mapActionToProps={
添加过滤器
};
导出默认连接(null,mapActionToProps)(日期拾取);
handleChange函数中的'date'参数是一个力矩对象,与用于设置initialState的参数类似,因此这不是问题所在

附加信息:如果我在
setState()之前和之后记录控制台日志,它会同时记录初始状态


有没有人遇到过这个问题或有什么想法?如果您需要查看我的redux,我可以用更多代码更新帖子,但我认为这不是问题所在,因为它可以很好地更新存储。

我找到了解决方案,action creator调用正在执行一些同步操作,整个UI线程被锁定,直到它完成所做的任何操作。因此,我们可以在setTimeout的帮助下稍微延迟调用,一切都会按预期进行

我不认为
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
    完成渲染后触发action creator

  • 另一种解决方案是在收到新道具时使用react lifecycle方法运行
    setState
    这样,在动作创建者返回道具并更改状态后,将触发
    setState

    componentWillRecieveProps (nextProps) {
        // check the related prop is changed
        // setState
    }
    
    但在react 17中,这种方法很快就会被弃用。新的稳定替代品如下


  • 使用回调方法,尝试以下操作:
    this.setState({date},()=>{this.props.addFilter(date,dashboardName,name);})谢谢你的帮助,不幸的是没有工作。设置存储但不设置ux哪个部分不工作,ui还是存储更新?存储正在更新(一如既往),但ux日期没有更改。我试着切换回叫以检查控制台是否抛出任何错误?你也应该发布相关代码,这将帮助一些用户更好地理解实现。旧问题,但一旦
    setTimeout
    完成,用户体验就会重置
    static getDerivedStateFromProps(nextProps, prevState) {
        // check the related prop is changed
        // setState
    }