Reactjs Redux商店没有';单击第一个按钮时不更新
我想使用redux,但仍然可以通过本地状态控制引导反应表中呈现的内容。因此,在componentDidMount中,我获取数据,当我尝试通过一个按钮进行筛选时,我将状态设置为一个名为“itemsToDisplay”的字段,然后我想将其作为表的数据。但是单击只在第二次工作,当我在render/componentDidMount中记录状态时,它是未定义的 我尝试了不同的条件来呈现表的数据字段prop中的项,但没有成功。我还尝试在componentWillMount中设置状态Reactjs Redux商店没有';单击第一个按钮时不更新,reactjs,redux,jsx,state-management,react-bootstrap-table,Reactjs,Redux,Jsx,State Management,React Bootstrap Table,我想使用redux,但仍然可以通过本地状态控制引导反应表中呈现的内容。因此,在componentDidMount中,我获取数据,当我尝试通过一个按钮进行筛选时,我将状态设置为一个名为“itemsToDisplay”的字段,然后我想将其作为表的数据。但是单击只在第二次工作,当我在render/componentDidMount中记录状态时,它是未定义的 我尝试了不同的条件来呈现表的数据字段prop中的项,但没有成功。我还尝试在componentWillMount中设置状态 class Delive
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);
类传递扩展组件{
建造师(道具){
超级(道具);
此.state={
itemsToDisplay:this.props.deliveries,
};
}
componentDidMount(){
this.props.getDeliveries();
this.setState(prev=>{
返回{
…上一页,
itemsToDisplay:this.props.deliveries,
}
})
}
过滤器未交付=()=>{
this.props.filterUndelivered();
this.setState(prev=>{
返回{
…上一页,
itemsToDisplay:this.props.undelivered_项目,
}
})
};
getFilters=()=>{
返回(
到时候
未交付
);
};
render(){
const{itemsToDisplay}=this.state;
常量选项={
insertBtn:this.createCustomInsertButton,
searchField:this.createCustomSearchField,
};
返回(
交货监视器
{this.getFilters()}
交付#
卖方
地址
场地
窗尾
到期日
地位
)
}
}
常量mapStateToProps=状态=>{
返回{
交货:state.deliveriesReducer.deliveries,
未送达的_项:state.deliveriesReducer.undelivered_项,
}
};
const mapDispatchToProps=(调度)=>{
返回bindActionCreators({getDeliveries,filterUndelivered},dispatch);
};
导出默认连接(mapStateToProps、mapDispatchToProps)(交付);
当数据属性的条件正确时,预期结果是能够在第一次单击时进行筛选。尝试修改代码,如下所示:
filterUndelivered = () => {
this.props.filterUndelivered();
};
componentWillReceiveProps = nextProps => {
if (nextProps.undelivered_items !== undefined) {
this.setState({ itemsToDisplay: nextProps.undelivered_items });
}
};
另外,在浏览器中安装Redux开发工具并分析应用程序状态。这可能会让您对该问题有更多的了解
铬:
Firefox:在将数据加载到表中之前,执行简单的检查数据是否可用
{
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>
}
{
itemsToDisplay.Length>0&&
交付#
卖方
地址
场地
窗尾
到期日
地位
}
为什么您的组件中还有另一个真相来源(状态)?基本上,将道具存储在组件状态是一种不好的做法(当然也有一些情况,但我认为这里不需要)
我认为您的组件应该只接收单个项目
道具,该道具将显示已交付或未交付的项目。您的操作将负责根据您在getDeliveries/filterUndelivered操作中设置的某种过滤器,在items
道具中传递已交付或未交付的项目
这样,您将始终将项目
道具传递给引导可接受的数据
道具,并且您的redux将负责在组件项目
道具中传递正确的项目(已交付或未交付)
这种方法的另一个优点是,如果要向项目中添加另一种过滤器(比如搜索查询),那么只需扩展redux过滤器状态并添加searchQuery
属性。这样,您就可以轻松地将新过滤器应用于您的项目,并且您的组件基本上不需要任何更改
这是一个简单的todo示例,带有简单的筛选功能,您可以应用于您的案例。试试这个,可能会有所帮助
...
componentDidMount() {
this.props.getDeliveries();
}
...
componentWillReceiveProps(recievedProps) {
if (this.props.deliveries != recievedProps.deliveries) {
this.setState({
itemsToDisplay: recievedProps.deliveries
})
}
}
...
我过去也有同样的问题。你检查过Redux的数据流吗?我检查过。从动作到减速器,数据看起来都很好,组件正确地接收数据。由于某些原因,第一次单击会将“itemsToDisplay”保留为未定义,然后在第二次单击时其工作正常。是否有可能是同步问题?尝试使用componentWillReceiveProps(nextProps)我尝试了它,但逻辑功能仍然相同:第一次单击no go,第二次点击有效。你对开发工具感到厌倦了吗..你在状态中看到第一次点击的数据了吗?是的,在Redux开发工具中,第一次点击和存储正确更新后,状态会发生变化。在组件中获取回调将在第一次点击时收到Props?。添加一些控制台日志,看看实际上,我通过@prasobh.kollattu的回答解决了这个问题,但是请注意,setState函数还需要一个扩展,以使前一个状态精确:componentWillReceiveProps=nextProps=>{if(nextProps.undelivered_items!==undefined){this.setState(prev=>{return{…prev,itemsToDisplay:nextProps.undelivered_items}}}}; 代码>