reducer中的Redux状态不是最新的?

时间:2018-04-02 19:17:18

标签: redux react-redux state redux-thunk

我正在使用React / Redux构建一个应用程序,我有一组产品,这些产品异步加载到Redux状态,然后我想从中提取单个产品。但是,我写的用于执行此操作的reducer并不工​​作,因为它将状态注册为null。这让我感到困惑,因为在返回操作之前调用thunk action creator中的getState()并触发reducer正在使用产品数组记录正确的状态。

这是我的代码中的错误还是仅仅是redux状态更新的一部分?

行动创作者:getSingleProduct

export const getSingleProduct = productName => (dispatch, getState) => {
  const action = { type: 'GET_SINGLE_PRODUCT', productName };
  if (!getState().products.length) return dispatch(getAllProducts())
    .then(() => {
      console.log('STATE IN ACTION CREATOR THEN BLOCK', getState());
      return dispatch(action);
    })
    .catch(console.log);
  else return action;
}

REDUCER:currentProduct

const currentProduct = (state = null, action) => {
switch (action.type) {
    case 'GET_SINGLE_PRODUCT':
      console.log('STATE IN REDUCER', state);
      return state.products.filter(prod => prod.name.toLowerCase() === action.productName)[0];
      break;
    default:
      return state;
  }
}

控制台日志输出

STATE IN ACTION CREATOR THEN BLOCK 
{ basket: Array(0), products: Array(6), currentProduct: null }


STATE IN REDUCER
null

2 个答案:

答案 0 :(得分:1)

State为null,因为您在第一次函数调用时将其定义为null。 操作完成后的console.log状态,您会看到值运行。 返回修改状态是错误的。应该回归新的状态。

const currentProduct = (state = null, action) => {
 switch (action.type) {
  case 'GET_SINGLE_PRODUCT':
    console.log('STATE IN REDUCER', state);
    const products = state.products.slice().filter(prod => prod.name.toLowerCase() === action.productName)[0];

    return { ...state, products } 
    break;
  default:
   return state;
 }
}

答案 1 :(得分:0)

减速器状态实际上是最新的,问题是对减速器状态如何工作的误解。我试图利用从reducer的state参数中无法获得的依赖状态。我的解决方案是将此信息从依赖状态传递到操作对象上。

<强>动作

export const getSingleProduct = (productName, products = []) => (dispatch, getState) => {
  let action = {
    type: 'GET_SINGLE_PRODUCT',
    productName,
    products: getState().products
  }
  if (!action.products.length) dispatch(getAllProducts())
    .then(() => {
      action = Object.assign({}, action, { products: getState().products });
      dispatch(action);
    })
    .catch(console.log);
  else return action;
}

<强>减速器

const currentProduct = (state = {}, action) => {
  switch (action.type) {
    case 'GET_SINGLE_PRODUCT':
      const currentProduct = action.products.filter(prod => prod.name.toLowerCase() === action.productName)[0];
      return Object.assign({}, state, currentProduct);
    default:
      return state;
  }
}