我在React-Redux中很新 . 正在处理申请 . 问题是我遇到了Redux actionCreator异步执行的一些问题,可能是 .
以下是我的组件 . 说,我想从 componentDidMount()
或onclick事件监听器调用actionCreator .
class Dashboard extends PureComponent {
componentDidMount() {
this.props.getProductsAndPackages();
let something = [];
something = this.props.products;
}
....................................
}
或者,函数 this.props.getProductsAndPackages();
可以是一个onClick事件处理程序,它执行相同的操作,上下文是相同的 . 在我第一次解释我的代码后,我会问我的问题 .
在我的仪表板容器的下方:
Dashboard.propTypes = {
getProductsAndPackages: PropTypes.func.isRequired,
products: PropTypes.array.isRequired,
.......................
};
const mapStateToProps = (state) => {
return {
.....................
products: state.products.products,
...................
};
};
const mapDispatchToProps = (dispatch) => {
return {
getProductsAndPackages: () => dispatch(getProductsAndPackagesActionCreator()),
};
};
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Dashboard));
我的actionCreator如下:
export const getProductsAndPackagesActionCreator = () => {
return (dispatch) => {
dispatch(productsIsLoading(true));
let url = 'xyz';
if(!!localStorage.getItem('_token')) {
const local_token = localStorage.getItem('_token');
const fullToken = 'Bearer '.concat(local_token);
axios.get(url, {headers: {Authorization: fullToken}})
.then(response => {
dispatch(productsIsLoading(false));
if (response.data.statusCode === 200) {
dispatch(productsFetched(true));
dispatch(products(response.data.data));
} else {
dispatch(productsFetched(false));
dispatch(productsErrors(response.data.message));
}
})
.catch(error => {
});
} else {
axios.get(url)
.then(response => {
dispatch(productsIsLoading(false));
if (response.data.statusCode === 200) {
dispatch(productsFetched(true));
dispatch(products(response.data.data));
} else {
dispatch(productsFetched(false));
dispatch(productsErrors(response.data.message));
}
})
.catch(error => {
console.log(error);
dispatch(productsIsLoading(false));
dispatch(productsErrors(error.message));
});
}
};
};
现在,我希望我的 getProductsAndPackagesActionCreator()
返回一个Promise或任何允许我的 something
变量获取从服务器返回的实际数据的东西 . 现在,当我获得实际数据时,行 something=this.props.products
已经执行,我回到了为 products
设置的initialValue .
我知道,每当我收到填充的 products
时,组件都会重新渲染,但这对我的决策没有帮助 .
顺便说一下,我正在使用 redux-thunk
.
我现在应该怎么做 ?对不起这么长的帖子 .
2 回答
实际上,我想要
getProductsAndPackagesActionCreator()
返回一个承诺,说实话,这很简单 . 我想出如果你只是axios.get()
或axios.post()
,它将返回一个承诺 . 因此,修改后的代码如下所示:然后,我可以在
componentDidMount()
或任何onClick事件中执行类似下面的操作:如果有任何问题,请随时告诉我 .
我认为你接近得到你想要的东西 . 首先,您应该了解redux操作和响应动作(如setState)是异步的,因此您必须应用逻辑来记住这一点 . 我将在某些方面解释我的想法:
您已将动作创建者调用到正确的位置 componentDidMount ,如果需要,您也可以在任何onClick中调用此动作 .
一旦你发出动作,你就会改变你的redux状态设置加载为true我想 . 所以现在你可以在渲染函数中访问这个属性,这样你就可以渲染一个Loader,直到你的api调用结束 .
当您的ajax功能完成时,如果有错误,我认为您将加载设置为false并更新您的产品数据,因此您现在可以在仪表板中呈现已加载的产品 .
您确定必须将空产品数组与收到的数据进行比较吗?也许您可以检查渲染功能
if (!this.props.products.length) return null
,当您加载页面时,您将看到一个加载器功能,稍后您将看到包含产品的仪表板 .如果您确实需要将以前的产品与收到的产品进行比较 componentDidUpdate 是您的方法 . 在这种方法中,你可以访问你以前的道具并与实际道具进行比较,小心比较数组,记住[] === []是假的 . 也许你可以比较长度,比如
只是说在渲染之后执行componentDidUpdate,所以要小心你的代码不要执行额外的渲染 .
希望它有所帮助,如果你不明白任何只是告诉我:)