调度操作不影响redux store的状态

时间:2018-06-13 08:52:32

标签: react-redux console.log

我正在开发一个应用程序来管理React-Redux中的开支,此时预期的行为是开始显示在我的控制台内的开销数组中的不同费用,并且它没有发生。我仍然得到一个空数组。

这就是我在app.js中所拥有的:

import React from 'react';
import ReactDOM from 'react-dom';
import AppRouter from './routers/AppRouter';
import configureStore from './store/configureStore';
import { addExpense } from './actions/expenses';
import { setTextFilter } from './actions/filters';
import getVisibleExpenses from './selectors/expenses';
import 'normalize.css/normalize.css';
import './styles/styles.scss';
const store = configureStore();
store.dispatch(addExpense({ description: 'Water bill' }));
console.log(store.getState());
ReactDOM.render(<AppRouter />, document.getElementById('app'));

这是我的/actions/expenses文件:

import uuid from 'uuid';
// ADD EXPENSE
export const addExpense = ({
  description = '',
  note = '',
  amount = 0,
  createdAt = 0
} = {}) => ({
  type: 'ADD EXPENSE',
  expense: {
    id: uuid(),
    description,
    note,
    amount,
    createdAt
  }
});
// REMOVE EXPENSE
export const removeExpense = ({ id } = {}) => ({
  type: 'REMOVE_EXPENSE',
  id
});
// EDIT EXPENSE
export const editExpense = (id, updates) => ({
  type: 'EDIT_EXPENSE',
  id,
  updates
});

这是我的actions/filters文件:

// SET TEXT FILTER
export const setTextFilter = (text = '') => ({
  type: 'SET_TEXT_FILTER',
  text
});
// SORT BY DATE
export const sortByDate = () => ({
  type: 'SORT_BY_DATE'
});
// SORT BY AMOUNT
export const sortByAmount = () => ({
  type: 'SORT_BY_AMOUNT'
});
// SET START DATE
export const setStartDate = (startDate) => ({
  type: 'SET_START_DATE',
  startDate
});
// SET END DATE
export const setEndDate = (endDate) => ({
  type: 'SET_END_DATE',
  endDate
});

这是我的selectors/expenses文件:

export default (expenses, { text, sortBy, startDate, endDate }) => {
  return expenses
    .filter((expense) => {
      const startDateMatch =
        typeof startDate !== 'number' || expense.createdAt >= startDate;
      const endDateMatch =
        typeof endDate !== 'number' || expense.createdAt >= endDate;
      const textMatch = expense.description
        .toLowerCase()
        .includes(text.toLowerCase());
      return startDateMatch && endDateMatch && textMatch;
    })
    .sort((a, b) => {
      if (sortBy === 'date') {
        return a.createdAt < b.createdAt ? 1 : -1;
      } else if (sortBy === 'amount') {
        return a.amount < b.amount ? 1 : -1;
      }
    });
};

我没有在命令行中收到任何错误,但我继续进入控制台:

{expenses: Array(0), filters {...}
expenses []

这是我的reducer / expenses.js文件:

const expensesReducerDefaultState = [];

export default (state = expensesReducerDefaultState, action) => {
  switch (action.type) {
    case 'ADD_EXPENSE':
      return [...state, action.expense];
    case 'REMOVE_EXPENSE':
      return state.filter(({ id }) => id !== action.id);
    case 'EDIT_EXPENSE':
      return state.map((expense) => {
        if (expense.id === action.id) {
          return {
            ...expense,
            ...action.updates
          };
        } else {
          return expense;
        }
      });
    default:
      return state;
  }
};

这是我的reducers / filters.js文件:

const filtersReducerDefaultState = {
  text: '',
  sortBy: 'date',
  startDate: undefined,
  endDate: undefined
};

export default (state = filtersReducerDefaultState, action) => {
  switch (action.type) {
    case 'SET_TEXT_FILTER':
      return {
        ...state,
        text: action.text
      };
    case 'SORT_BY_AMOUNT':
      return {
        ...state,
        sortBy: 'amount'
      };
    case 'SORT_BY_DATE':
      return {
        ...state,
        sortBy: 'date'
      };
    case 'SET_START_DATE':
      return {
        ...state,
        startDate: action.startDate
      };
    case 'SET_END_DATE':
      return {
        ...state,
        endDate: action.endDate
      };
    default:
      return state;
  }
};

1 个答案:

答案 0 :(得分:0)

根据文档(https://redux.js.org/api-reference/store#dispatch-action),store.dispatch是同步的,您的addExpense函数也是同步的。

因此,问题必须在处理操作的reducer中。您没有处理此操作的reducer,可能导致默认行为,即返回原始状态(这取决于您的reducer代码),或者reducer中发生错误,导致此操作无法进行任何更改

这两种情况都不太可能导致抛出异常(同样,取决于你的reducer代码)。

修改

在您的/actions/expenses文件中,您将操作类型设置为ADD EXPENSE,但在缩减器中,您的switch会查找ADD_EXPENSE!因此,要么在/actions/expenses文件中添加下划线,要么从reducer中删除它。

没有控制台错误,因为您的代码将其视为默认情况。

将来,我建议控制台在action.type的默认情况下记录switch,以确保您不会遗漏任何操作。此外,您应该对动作类型使用枚举,而不仅仅是字符串,因此要犯同样的错误要困难得多。请参阅以下示例:

减速机:

import actionType from "../actionsEnum";

const expensesReducerDefaultState = [];

export default (state = expensesReducerDefaultState, action) => {
  switch (action.type) {
    case actionType.ADD_EXPENSE:
      return [...state, action.expense];
    // ...
    default:
      return state;
  }
};

枚举文件:

const actionType = {
    ADD_EXPENSE: "ADD_EXPENSE"
};

// Prevent new actions from being added or deleted outside this file
export default Object.freeze(actionType);