单击按钮后,Redux Store不会更新

时间:2019-07-18 08:58:01

标签: reactjs redux jsx state-management react-bootstrap-table

我想使用redux,但仍通过本地状态控制bootstrap-react-table中呈现的内容。因此,在componentDidMount中,我正在获取数据,当我尝试通过按钮进行过滤时,将setState设置为名为“ itemsToDisplay”的字段,然后将其用作表的数据。但是单击仅在第二次有效,并且当我在render / componentDidMount中记录状态时,它是未定义的。

我尝试了不同的条件来渲染表的数据字段prop中的项目,但未成功。我也尝试在componentWillMount中设置状态。

class Deliveries extends Component {
  constructor(props) {
    super(props);
    this.state = {
      itemsToDisplay: this.props.deliveries,
    };
  }

  componentDidMount() {
    this.props.getDeliveries();
    this.setState(prev => {
      return {
        ...prev,
        itemsToDisplay: this.props.deliveries,
      }
    })
  }

  filterUndelivered = () => {
    this.props.filterUndelivered();
    this.setState(prev => {
      return {
        ...prev,
        itemsToDisplay: this.props.undelivered_items,
      }
    })
  };

  getFilters = () => {
    return (
      <div>
        <Button className="m-1" color="primary">By time</Button>
        <Button className="m-1" color="primary" onClick={ this.filterUndelivered }>Not delivered</Button>
      </div>
    );
  };

  render() {
    const { itemsToDisplay } = this.state;

    const options = {
      insertBtn: this.createCustomInsertButton,
      searchField: this.createCustomSearchField,
    };

    return (
      <div className="animated fadeIn">

        <div className="d-flex justify-content-between">
          <div className="font-weight-bold mt-2">Deliveries Monitor</div>
          <div className="d-flex justify-content-end">
            {this.getFilters()}
          </div>
        </div>
        <BootstrapTable
          data={ itemsToDisplay ? itemsToDisplay : this.props.deliveries }
          version="4"
          search
          hover
          pagination
          bordered={false}
          headerStyle={{ background: "#20a8d8" }}
          bodyStyle={{ cursor: "pointer"}}
          options={ options }
        >
          <TableHeaderColumn isKey dataField="delivery_id">Delivery#</TableHeaderColumn>
          <TableHeaderColumn dataField="seller">Seller</TableHeaderColumn>
          <TableHeaderColumn dataField="address">Address</TableHeaderColumn>
          <TableHeaderColumn dataField="site">Site</TableHeaderColumn>
          <TableHeaderColumn dataField="end_of_window">End of window</TableHeaderColumn>
          <TableHeaderColumn dataField="due_date">Due date</TableHeaderColumn>
          <TableHeaderColumn dataField="status">Status</TableHeaderColumn>
        </BootstrapTable>
      </div>
    )
  }
}

const mapStateToProps = state => {
  return {
    deliveries: state.deliveriesReducer.deliveries,
    undelivered_items: state.deliveriesReducer.undelivered_items,
  }
};

const mapDispatchToProps = (dispatch) => {
  return bindActionCreators({ getDeliveries, filterUndelivered }, dispatch);
};

export default connect(mapStateToProps, mapDispatchToProps)(Deliveries);

预期的结果是,在数据道具的条件正确的情况下,第一次单击时就可以对其进行过滤。

4 个答案:

答案 0 :(得分:1)

尝试如下修改您的代码:

  filterUndelivered = () => {
    this.props.filterUndelivered();
  };

  componentWillReceiveProps = nextProps => {
    if (nextProps.undelivered_items !== undefined) {
      this.setState({ itemsToDisplay: nextProps.undelivered_items });
    }
  };

还可以在浏览器中安装Redux开发工具并分析应用程序状态,这可能会使您对该问题有更多的了解。

Chrome浏览器:https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd

Firefox:https://addons.mozilla.org/en-US/firefox/addon/reduxdevtools/

答案 1 :(得分:0)

在将数据加载到表之前执行简单的检查,看看是否有数据

{
  itemsToDisplay.lenght > 0 &&
    <BootstrapTable
              data={ itemsToDisplay }
              version="4"
              search
              hover
              pagination
              bordered={false}
              headerStyle={{ background: "#20a8d8" }}
              bodyStyle={{ cursor: "pointer"}}
              options={ options }
            >
              <TableHeaderColumn isKey dataField="delivery_id">Delivery#</TableHeaderColumn>
              <TableHeaderColumn dataField="seller">Seller</TableHeaderColumn>
              <TableHeaderColumn dataField="address">Address</TableHeaderColumn>
              <TableHeaderColumn dataField="site">Site</TableHeaderColumn>
              <TableHeaderColumn dataField="end_of_window">End of window</TableHeaderColumn>
              <TableHeaderColumn dataField="due_date">Due date</TableHeaderColumn>
              <TableHeaderColumn dataField="status">Status</TableHeaderColumn>
            </BootstrapTable>
}

答案 2 :(得分:0)

为什么您的组件中还有另一个真理(状态)来源?基本上,将道具存储在组件状态中是一种不好的做法(当然有些情况,但我认为您不需要在这里使用它)。

我认为您的组件应该只接收一个items道具,以显示已交付或未交付的商品。您的操作将负责根据您将在getDeliveries / filterUndelivered操作中设置的某种过滤器,在items道具中传递已交付或未交付的商品。

这样,您将始终将items道具传递给BootstrapTable data道具,并且您的redux将负责在组件{{1}中传递正确的项目(已交付或未交付) }道具。

此方法的另一个优点是,如果您要向项目添加另一种过滤器(让我们说搜索查询),则只需扩展redux过滤器状态并添加items属性。这样,您就可以轻松地将新的过滤器应用于您的商品,并且您的组件基本上不需要任何更改。

Here是一个简单的待办事项示例,具有简单的过滤功能,可用于您的案例。

答案 3 :(得分:0)

尝试一下,也许可以帮忙

...
componentDidMount() {
    this.props.getDeliveries();    
}
...
componentWillReceiveProps(recievedProps) {
    if (this.props.deliveries != recievedProps.deliveries) {
        this.setState({
            itemsToDisplay: recievedProps.deliveries
        })
    }
}
...