我想使用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);
预期的结果是,在数据道具的条件正确的情况下,第一次单击时就可以对其进行过滤。
答案 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
})
}
}
...