由于how data flows通过React-Redux应用程序,在商店中更新的数据在React组件中不可用,直到该组件重新渲染为止。
我的要求是,在给定的组件中,我想使用更新的存储,而无需重新渲染该组件。我想做这样的事情:
import React, { Component } from "react";
import { bindActionCreators } from "redux";
import { connect } from "react-redux";
import * as AActions from "../aactions";
import * as BActions from "../bactions";
import * as CActions from "../cactions";
class MyComponent extends Component<Props>{
constructor(props){
super(props);
this.func = this.func.bind(this);
};
func(){
// Add item to A
this.props.addAItem("value");
// Get id of newly added item in A
let addedA = this.props.A.find(a => a.name === "value");
// Insert new items in B with the id of A
this.props.addBItem(addedA.id, "valueB");
// etc...
}
render(){
<div onClick={() => this.func()}>click me</div>
}
}
function mapStateToProps(state, props){
return {
A: state.A,
B: state.B,
C: state.C
};
}
function mapDispatchToProps(dispatch){
return bindActionCreators({...AActions, ...BActions, ...CActions}, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(MyComponent);
此操作不起作用,因为props
直到MyComponent重新渲染后才会更新。我无法调用this.props.A.find(a => a.name === "value");
,因为道具不会具有最新添加的“ A”值。就我而言,我等不及要重新渲染MyComponent。在MyComponent中访问最近状态有什么选择?
我已经做过这样的事情,但这绝对是可怕的,但是确实有效...
func(){
if (this.props.step1){
// Add item to A
this.props.addAItem("value");
this.props.setStep2();
} else if (this.props.step2) {
// Get id of newly added item in A
let addedA = this.props.A.find(a => a.name === "value");
this.props.setStep3();
}
// etc...
}
答案 0 :(得分:1)
好吧,如果我对问题的理解正确,那么您的func方法addItemA然后addItemB依赖于addItemA的响应,addItemA是异步操作,因此在addItemA操作中,添加项目时,您可以简单地从操作中返回promise解析时返回新创建元素的ID,在组件内部,您可以在
中处理then块func(){
// Add item to A
this.props.addAItem("value").then((id) => {
// no need to find the id now
// Insert new items in B with the id of A
this.props.addBItem(id, "valueB");
});
// etc...
}
希望有帮助
答案 1 :(得分:0)
反复来回 并进行测试,我碰到了很多墙,试图弄清楚这个,但最终弄清楚了。这就是您需要做的。
注意:这不被视为React Redux公共API的一部分,并且可能会在没有通知的情况下中断。我们确实认识到社区有一些必要的用例,并且会尝试使用户有可能在React Redux之上构建附加功能,但是我们对上下文的特定使用被视为实现细节。如果您还有其他用例,但当前的API尚未充分涵盖这些用例,请提出问题以讨论可能的API改进。 -https://react-redux.js.org/using-react-redux/accessing-store#using-reactreduxcontext-directly
确保您的反应软件包为16.8.3
或更高版本。确保您的 react-redux 软件包为7.1
或更高。由于新方法(在React 16.8.3中),您需要这些版本。React将Context传递给子组件。我们关心Context,因为 ReactReduxContext 是这种新的React Context API的工作方式。
ReactReduxContext是我们获取组件中商店当前状态所需要的魔力。请注意我们下面组件中的更改。
import React, { Component } from "react";
import { bindActionCreators } from "redux";
import { connect, ReactReduxContext } from "react-redux"; // CHANGED!
import * as AActions from "../aactions";
import * as BActions from "../bactions";
import * as CActions from "../cactions";
class MyComponent extends Component<Props>{
constructor(props){
super(props);
this.func = this.func.bind(this);
};
func(store){ // CHANGED!
// Add item to A
this.props.addAItem("value");
// Get id of newly added item in A
let addedA = store.getState().A.find(a => a.name === "value"); // CHANGED!
// Insert new items in B with the id of A
this.props.addBItem(addedA.id, "valueB");
// etc...
}
// CHANGED!
render(){
<ReactReduxContext.Consumer>
{({store}) => {
return <div onClick={() => this.func(store)}>click me</div>
}}
</ReactReduxContext.Consumer>
}
}
function mapStateToProps(state, props){
return {
A: state.A,
B: state.B,
C: state.C
};
}
function mapDispatchToProps(dispatch){
return bindActionCreators({...AActions, ...BActions, ...CActions}, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(MyComponent);
魔术是store.getState()
,它将返回更新的Redux存储。
我想指出的是,我对redux-thunk
进行了广泛的研究,但是这种方法并没有最终满足我的需求。主要问题是在组件中使用 bindActionCreators 。因为我正在使用 bindActionCreators ,所以我调用的任何操作都期望有一个空对象,该对象将被分派到Redux存储。
我尝试了多种方法尝试在操作中返回更新的Redux状态,但是由于我使用的是bindActionCreators,因此无法从给定操作返回Redux状态的值。不依赖要更新/重新呈现的组件本身而检索更新的Redux存储状态 的唯一方法是使用我上面概述的方法。
答案 2 :(得分:-1)
shouldComponentUpdate应该可以解决问题