从Redux状态拉出属性返回undefined,尽管它肯定有一个值

时间:2017-08-27 13:43:58

标签: reactjs redux

本周我一直在制作一个小应用程序来学习如何使用React和Redux,而且它一直很顺利,但这个问题让我感到头疼。

这是我的减速器的样子。

const initialiseState = {
  items: {},
  total: 0
}

function basket(state = initialiseState, action) {

  switch (action.type) {
    case ADD_TO_BASKET:
      if(action.sku){
        const quantity = state.items[action.sku] || 0;
        return {
          items: {...state.items, [action.sku]: quantity + 1},
          total:  parseInt(state.total,10) + parseInt(action.price, 10)
        };
      return state
    }

    case REMOVE_FROM_BASKET:
      if(action.sku) {

        // const {[action.sku]: quantity, ...items } = state.items;

        const quantity  = state.items[action.sku];
        const { items } = state;
        if(quantity && quantity > 1) {
          const x = {
            items: {...state, [action.sku]: quantity - 1},
            total: parseInt(state.total,10) - parseInt(action.price, 10)
          };
          console.log(x)
          return;
        } else {
          return state;
        }
      } else {
        return state;
      }
    default:
      return state;
  }
}

我对ADD_TO_BASKET没有任何问题,但是当我尝试从购物篮quantity中移除某个商品时,它将以未定义的形式返回。我将调试器放在代码中拉出该值的位置,当我在控制台中运行state.items[action.sku]时,它会带回值。

我刚刚离开调试代码,但您应该了解我正在尝试做的事情。

我不确定您需要查看我的代码的其他部分,以便在需要时我可以更新问题。

编辑:这是我开始调试之前的原始reducer代码,以及actions文件。

import { combineReducers } from 'redux'
import {
  ADD_TO_BASKET,
  REMOVE_FROM_BASKET
} from './actions'

const initialiseState = {
  items: {},
  total: 0
}

function basket(state = initialiseState, action) {

  switch (action.type) {
    case ADD_TO_BASKET:
      if(action.sku){
        const quantity = state.items[action.sku] || 0;
        return {
          items: {...state.items, [action.sku]: quantity + 1},
          total:  parseInt(state.total,10) + parseInt(action.price, 10)
        };
      return state
    }

    case REMOVE_FROM_BASKET:
      if(action.sku) {
        const {[action.sku]: quantity, ...items } = state.items;
        if(quantity && quantity > 1) {
          return {
            items: {...state, [action.sku]: quantity - 1},
            total: parseInt(state.total,10) - parseInt(action.price, 10)
          };
        } else {
          return state;
        }
      } else {
        return state;
      }
    default:
      return state;
  }
}

const coffeeApp = combineReducers({
  basket,
})

export default coffeeApp

actions.js

/*
 * action types
 */

export const ADD_TO_BASKET      = 'add to basket'
export const REMOVE_FROM_BASKET = 'remove from basket'
export const ADD_PRODUCTS       = 'add products json to state'

/*
 * action creators
 */

export function addToBasket(sku, price) {
  return { type: ADD_TO_BASKET, sku, price }
}

export function removeFromBasket(sku, price) {
  return { type: REMOVE_FROM_BASKET, sku, price }
}

export function addProducts(products) {
  return { type: ADD_PRODUCTS, payload: products }
}

编辑2:修复了错误的返回语句和减速器中的大括号。

代码已到达REMOVE_FROM_BASKET语句,您可以看到here at this break point。并且quantity变量未定义。但是,在控制台中,我可以提取值here is a screen shot of the console

4 个答案:

答案 0 :(得分:1)

console.log(x)陈述之后,您没有立即归还任何内容。这就是你看到未定义的原因。尝试将该部分代码更新为:

...
if(quantity && quantity > 1) {
  const x = {
    items: {...state, [action.sku]: quantity - 1},
    total: parseInt(state.total,10) - parseInt(action.price, 10)
  };
  console.log(x)
  return x; // <<--- returning new state here!
} else {
  return state;
}
...

答案 1 :(得分:0)

您的交换机case中缺少单引号。有关详细信息,请参阅https://github.com/kalaikt/rearch-reactjs/blob/master/src/app/reducers/SearchReducers.jsx

const initialiseState = {
  items: {},
  total: 0
}

function basket(state = initialiseState, action) {

  switch (action.type) {
    case 'ADD_TO_BASKET':
      if(action.sku){
        const quantity = state.items[action.sku] || 0;
        return {
          items: {...state.items, [action.sku]: quantity + 1},
          total:  parseInt(state.total,10) + parseInt(action.price, 10)
        };
      return state
    }

    case 'REMOVE_FROM_BASKET':
      if(action.sku) {

        // const {[action.sku]: quantity, ...items } = state.items;

        const quantity  = state.items[action.sku];
        const { items } = state;
        if(quantity && quantity > 1) {
          const x = {
            items: {...state, [action.sku]: quantity - 1},
            total: parseInt(state.total,10) - parseInt(action.price, 10)
          };
          console.log(x)
          return;
        } else {
          return state;
        }
      } else {
        return state;
      }

    default:
      return state;
  }
}

答案 2 :(得分:0)

问题实际上是你的购物篮缩减函数中的括号,因为现在只有一个有效的案例陈述

让我向您展示当前代码正确缩进的问题:

function basket(state = initialiseState, action) {
  switch (action.type) {
    // the only valid case statement!
    case ADD_TO_BASKET:
      if(action.sku){
        const quantity = state.items[action.sku] || 0;
        return {
          items: {...state.items, [action.sku]: quantity + 1},
          total:  parseInt(state.total,10) + parseInt(action.price, 10)
        };
        // unreachable code!
        return state
      }
      // case inside case statement here!
      case REMOVE_FROM_BASKET:
        if(action.sku) {
          const {[action.sku]: quantity, ...items } = state.items;
          if(quantity && quantity > 1) {
            return {
              items: {...state, [action.sku]: quantity - 1},
              total: parseInt(state.total,10) - parseInt(action.price, 10)
            };
            return state;
          } else {
            return state;
          }
        } else {
          return state;
        }
      // default inside case statement here!
      default:
        return state;
  }
}

我很确定你知道怎么做但只是为了完成这里,你想要使用这样的东西:

function basket(state = initialiseState, action) {
  switch (action.type) {
    case ADD_TO_BASKET:
      if(action.sku) {
        const quantity = state.items[action.sku] || 0;
        return {
          items: {...state.items, [action.sku]: quantity + 1},
          total:  parseInt(state.total,10) + parseInt(action.price, 10)
        };
      } // <<--- proper closing of the if condition here
      return state;

    case REMOVE_FROM_BASKET:
      if(action.sku) {
        const {[action.sku]: quantity, ...items } = state.items;
        if(quantity && quantity > 1) {
          return {
            items: {...state, [action.sku]: quantity - 1},
            total: parseInt(state.total,10) - parseInt(action.price, 10)
          };
        } else {
          return state;
        }
      } else {
        return state;
      }

    default:
      return state;
  }
}

答案 3 :(得分:-1)

我开始工作,高级开发人员和我一样困惑,为什么这不起作用。我使用create-react-app创建了应用程序,因此我弹出了应用程序,以便我可以看到编译的javascript发生了什么。瞧,它看起来只是在弹出后工作,我不确定导致问题的是什么,但弹出应用修复了它。

如果有人知道为什么会发生这种情况,那么我很想知道。