Redux reducer:当数组没有对象数据时,将对象添加到数组



我正试图将AJAX调用返回的数据对象存储到Redux的reducer状态数组中。我有一些条件来检查获取的数据是否已经存在于reducer内部。

以下是我的问题:

  1. 调用AJAX调用操作的组件,它是mapDispatchToProps中的一个函数,会导致无限循环
  2. 减速器中的isProductLikedData状态未正确更新

你能告诉我缺了什么吗?

这是我的代码:

isProductLikedActions.js-获取isProductLikend数据的操作。response.data看起来像{status: 200, isProductLiked: boolean}

export function fetchIsProductLiked(productId) {
return function (dispatch) {
axios
.get(`/ajax/app/is_product_liked/${productId}`)
.then((response) => {
dispatch({
type: 'FETCH_IS_PRODUCT_LIKED_SUCCESS',
payload: { ...response.data, productId },
});
})
.catch((err) => {
dispatch({
type: 'FETCH_IS_PRODUCT_LIKED_REJECTED',
payload: err,
});
});
};
}

isProductLikedReducer.js-当array.length === 0时,我将action.payload对象添加到isProductLikedData数组中。之后,我想检查isProductLikedData中是否存在action.payload对象,以防止重复。如果没有重复,我想做[...state.isProductLikedData, action.payload]

const initialState = {
isProductLikedData: [],
fetching: false,
fetched: false,
error: null,
};
export default function reducer(state = initialState, action) {
switch (action.type) {
case 'FETCH_IS_PRODUCT_LIKED': {
return { ...state, fetching: true };
}
case 'FETCH_IS_PRODUCT_LIKED_SUCCESS': {
return {
...state,
fetching: false,
fetched: true,
isProductLikedData:
state.isProductLikedData.length === 0
? [action.payload]
: state.isProductLikedData.map((data) => {
if (data.productId === action.payload.productId) return;
if (data.productId !== action.payload.productId)
return action.payload ;
}),
};
}
case 'FETCH_IS_PRODUCT_LIKED_REJECTED': {
return {
...state,
fetching: false,
error: action.payload,
};
}
}
return state;
}

Products.js-products是在componentWillMount中获取的一个数组。一旦nextProps.products.fetched变为true,我想调用fetchIsProductLiked来获取isProductLiked`数据。但这会导致一个无限循环。

class Products extends React.Component {
...
componentWillMount() {
this.props.fetchProducts();
}
...
componentWillReceiveProps(nextProps) {
if (nextProps.products.fetched) {
nextProps.products.map((product) => {
this.props.fetchIsProductLiked(product.id);
}
}
render() {
...
}
}
export default Products;

第1期

调用AJAX调用操作的组件,它是mapDispatchToProps中的一个函数,会导致无限循环。

由于您在componentWillReceiveProps中使用的条件,您将看到无限调用。

在提取产品(数据(之后,nextProps.products.fetched总是true。此外,请注意,每次道具发生变化时都会调用componentWillReceiveProps。这引起了无限的呼叫。

解决方案1

如果您想在提取产品数据后调用fetchIsProductLiked,最好将旧的products数据与componentWillReceiveProps中的新数据进行比较,如下所示:

componentWillReceiveProps(nextProps) {
if (nextProps.products !== this.props.products) {
nextProps.products.forEach((product) => {
this.props.fetchIsProductLiked(product.id);
});
}
}

注意:您应该开始使用componentDidUpdate,因为componentWillReceiveProps正在被弃用。


第2期

reducer中的isProductLikedData状态未正确更新。

这不是正在更新,因为您使用了map。Map返回一个新数组(具有从回调返回的元素(,其长度相同(您希望添加一个新元素(。

解决方案2

如果只想在州中不存在数据时更新数据,可以使用某些数据来检查数据是否存在。并且,当返回false时,使用排列语法推送新数据:

case "FETCH_IS_PRODUCT_LIKED_SUCCESS": {
return {
...state,
fetching: false,
fetched: true,
isProductLikedData: state.isProductLikedData.some(
(d) => d.productId === action.payload.productId
)
? state.isProductLikedData
: [...state.isProductLikedData, action.payload],
};
}

相关内容

  • 没有找到相关文章

最新更新