错误:不变式失败:在 Next.js 中的调度之间检测到状态变化。

huangapple go评论72阅读模式
英文:

Error: Invariant failed: A state mutation was detected between dispatches in next js

问题

当我尝试从前端更改状态时,错误显示...

错误:不变性失败:在分派之间检测到状态突变,在路径 'products.productAttributes.0.attribute' 中。这可能会导致不正确的行为。 (https://redux.js.org/style-guide/style-guide#do-not-mutate-state)

我的Reducer:

import {
  GET_PRODUCTS_BY_QUERY,
  GET_PRODUCT_BY_ID,
  GET_PRODUCTS,
  PRODUCT_DATA_ON_PROGRESS,
  PRODUCT_DATA_SUBMIT_PROGRESS,
  OPEN_PRODUCT_SIDEBAR,
  BIND_PRODUCT_BASIC_INFO,
  BIND_PRODUCT_ATTRIBUTES,
} from '../action-types';
import { ProductBasicInfoModal, attributes } from '../model';

const initialState = {
  dataProgress: false,
  submitProductDataProgress: false,
  openProductSidebar: false,
  products: [],
  productAttributes: attributes,
  product: ProductBasicInfoModal,
  total: 1,
  queryParams: {},
  queryObj: {},
};

const productReducers = (state = initialState, action) => {
  switch (action.type) {
    case GET_PRODUCTS_BY_QUERY:
      return {
        ...state,
        products: action.products,
        total: action.total,
        queryParams: action.queryParams,
        queryObj: action.queryObj,
      };

    case GET_PRODUCT_BY_ID:
      return {
        ...state,
        product: action.product,
      };
    case BIND_PRODUCT_BASIC_INFO:
      return {
        ...state,
        product: action.product,
      };
    case BIND_PRODUCT_ATTRIBUTES:
      return {
        ...state,
        productAttributes: action.attributes,
      };
    case PRODUCT_DATA_ON_PROGRESS:
      return {
        ...state,
        dataProgress: action.dataProgress,
      };

    case PRODUCT_DATA_SUBMIT_PROGRESS:
      return {
        ...state,
        submitProductDataProgress: action.submitProductDataProgress,
      };
    case OPEN_PRODUCT_SIDEBAR:
      return {
        ...state,
        openProductSidebar: action.openProductSidebar,
      };

    default:
      return state;
  }
};
export default productReducers;

然后我的Action:

export const bindProductAttributes = (data) => (dispatch) => {
  dispatch({
    type: BIND_PRODUCT_ATTRIBUTES,
    attributes: data,
  });
};

这是我的组件函数:

const dispatch = useDispatch();
const { product, productAttributes } = useSelector(
  ({ products }) => products
);
const handleDropdownOChange = (data, e, rowId) => {
  const { name } = e;
  const attributes = [...productAttributes].map((att) => {
    if (att.id === rowId) {
      att[name] = data;
    }
    return att;
  });
  dispatch(bindProductAttributes(attributes));
};

当触发动作 handleDropdownOChange 时,我遇到了问题!

请帮助我!

英文:

When I try to change the state from the front-end, the error shows...

Error: Invariant failed: A state mutation was detected between dispatches, in the path 'products.productAttributes.0.attribute'. This may cause incorrect behavior. (https://redux.js.org/style-guide/style-guide#do-not-mutate-state)

My Reducer :

    import {
GET_PRODUCTS_BY_QUERY,
GET_PRODUCT_BY_ID,
GET_PRODUCTS,
PRODUCT_DATA_ON_PROGRESS,
PRODUCT_DATA_SUBMIT_PROGRESS,
OPEN_PRODUCT_SIDEBAR,
BIND_PRODUCT_BASIC_INFO,
BIND_PRODUCT_ATTRIBUTES,
} from '../action-types';
import { ProductBasicInfoModal, attributes } from '../model';
const initialState = {
dataProgress: false,
submitProductDataProgress: false,
openProductSidebar: false,
products: [],
productAttributes: attributes,
product: ProductBasicInfoModal,
total: 1,
queryParams: {},
queryObj: {},
};
const productReducers = (state = initialState, action) => {
switch (action.type) {
case GET_PRODUCTS_BY_QUERY:
return {
...state,
products: action.products,
total: action.total,
queryParams: action.queryParams,
queryObj: action.queryObj,
};
case GET_PRODUCT_BY_ID:
return {
...state,
product: action.product,
};
case BIND_PRODUCT_BASIC_INFO:
return {
...state,
product: action.product,
};
case BIND_PRODUCT_ATTRIBUTES:
return {
...state,
productAttributes: action.attributes,
};
case PRODUCT_DATA_ON_PROGRESS:
return {
...state,
dataProgress: action.dataProgress,
};
case PRODUCT_DATA_SUBMIT_PROGRESS:
return {
...state,
submitProductDataProgress: action.submitProductDataProgress,
};
case OPEN_PRODUCT_SIDEBAR:
return {
...state,
openProductSidebar: action.openProductSidebar,
};
default:
return state;
}
};
export default productReducers;

Then My Action:

export const bindProductAttributes = (data) => (dispatch) => {
dispatch({
type: BIND_PRODUCT_ATTRIBUTES,
attributes: data,
});
};

Here is my Component Function:

**

const dispatch = useDispatch();
const { product, productAttributes } = useSelector(
({ products }) => products
);
const handleDropdownOChange = (data, e, rowId) => {
const { name } = e;
const attributes = [...productAttributes].map((att) => {
if (att.id === rowId) {
att[name] = data;
}
return att;
});
dispatch(bindProductAttributes(attributes));
};

**

I faced the problem when the action handleDropdownOChange is fired!

Please Help me !

答案1

得分: 1

问题很可能出在 att[name] = data; 这一行。这会导致对 att 进行_变异_,而该变量最初来自Redux存储。不要这样做 错误:不变式失败:在 Next.js 中的调度之间检测到状态变化。

在这里_最好的_解决方案是,改为派发一个可能包含行ID和数据的操作,然后让_减速器_来处理更新:

你还应该使用Redux Toolkit的createSlice来编写该减速器。

这些要素一起将使管理更新变得更简单,并且消除了意外的变异问题。

英文:

The issue is most likely the line att[name] = data;. This mutates att, and that variable is an object that originally came from the Redux store. Don't do that 错误:不变式失败:在 Next.js 中的调度之间检测到状态变化。

The best answer here is to instead dispatch an action that might contain the row ID and the data, and let the reducer take care of handling the update:

You should also use Redux Toolkit's createSlice to write that reducer.

Those pieces together will make it much simpler to manage the update, and eliminate the accidental mutation problem.

huangapple
  • 本文由 发表于 2023年3月8日 17:33:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/75671365.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定