如何在 Angualr2 项目中使用 Redux

Redux 是一个基于 Flux 架构的 JavaScript 应用程序状态管理库。它被广泛用于 React 应用程序,但也可以用于任何 JavaScript 应用程序。 在本文中,我们将学习如何在 Angular2 应用程序中使用 Redux。

Redux 的基本原则

在学习如何使用 Redux 之前,让我们首先了解一下 Redux 的基本原则。

Redux 有 3 个基本原则:

  1. 单一数据源: 整个应用的状态被存储在单个对象中,成为 store。 这使得它更容易跟踪和管理应用程序的状态。

  2. 状态只读: 状态是只读的,不能从组件中直接修改它。 必须通过派遣操作 (action) 来改变状态。 派遣操作是一个对象,它描述了如何改变状态。

  3. 使用纯函数来改变状态: 使用纯函数来描述如何改变状态。一个纯函数返回一个新的状态,而不会改变任何状态。 这使得它更容易测试和理解。

前置条件

在我们开始之前,确保您已经安装了下面的依赖项:

  • Angular2 (2.0.0+)
  • Redux (3.0.0+)
  • redux-thunk (2.0.0+)

安装依赖项

首先安装 Redux 和 redux-thunk:

npm install --save redux redux-thunk

创建 Redux Store

首先,让我们创建 Redux Store。 Store 包含整个应用程序的状态。 让我们创建一个名为 store.ts 的文件。

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { rootReducer } from './reducers';

export const store = createStore(
  rootReducer,
  {},
  applyMiddleware(thunk)
);

我们使用 createStore 方法来创建一个新的 Store。 第一个参数是一个根 Reducer,我们稍后将复述并创建它。 第二个参数是一个初始状态对象。 这里我们将它保留为空对象。 第三个参数是一个中间件,我们在这里使用 redux-thunk。

创建 Redux Reducer

Reducers 接收操作 (action) 和当前状态 (state),并返回一个新的状态。 让我们创建一个名为 reducers.ts 的文件。

import { combineReducers } from 'redux';

export const rootReducer = combineReducers({
  // add your reducers here
});

combineReducers 函数是用于将多个 Reducer 合并到一个单一的 Reducer 中的。 在这里,我们有一个根 Reducer,我们将在此之后添加其他 Reducer。

添加 Redux Reducer

在添加 Reducer 之前,我们需要定义接口来描述我们应用程序的状态。 让我们创建一个名为 state.ts 的文件。

export interface AppState {
  // define your state here
}

export const initialState: AppState = {
  // set your initial state here
};

接下来,我们创建一个 Todo Reducer,并将其添加到 rootReducer 中。

import { combineReducers } from 'redux';

import { Action } from '@ngrx/store';
import { ADD_TODO, REMOVE_TODO, TOGGLE_TODO } from './todo.actions';
import { AppState } from './state';

export function todoReducer(state = [], action: Action) {
  switch (action.type) {
    case ADD_TODO:
      return [...state, action.payload];

    case TOGGLE_TODO:
      return state.map(todo => {
        if (todo.id === action.payload) {
          return Object.assign({}, todo, {
            completed: !todo.completed
          });
        }

        return todo;
      });

    case REMOVE_TODO:
      return state.filter(todo => todo.id !== action.payload);

    default:
      return state;
  }
}

export const rootReducer = combineReducers({
  todo: todoReducer
});

export function getTodoState(state: AppState) {
  return state.todo;
}

在这里,我们创建了一个 Todo Reducer,它处理 ADD_TODO, REMOVE_TODOTOGGLE_TODO 操作。 等等。它返回新的应用程序状态。

创建 Redux Actions

接下来,我们需要创建操作 (action),这些操作描述如何改变状态。 我们将创建一个新文件,名为 actions.ts,其中包含了 Todo 操作 (action) 的常量字符串和操作生成器 (action creators)。

import { Action } from '@ngrx/store';
import { Todo } from './todo';

export const ADD_TODO = '[Todo] Add Todo';
export const REMOVE_TODO = '[Todo] Remove Todo';
export const TOGGLE_TODO = '[Todo] Toggle Todo';

export class AddTodoAction implements Action {
  readonly type = ADD_TODO;

  constructor(public payload: Todo) {}
}

export class RemoveTodoAction implements Action {
  readonly type = REMOVE_TODO;

  constructor(public payload: number) {}
}

export class ToggleTodoAction implements Action {
  readonly type = TOGGLE_TODO;

  constructor(public payload: number) {}
}

export type Actions =
  | AddTodoAction
  | RemoveTodoAction
  | ToggleTodoAction;

在这里,我们定义了 ADD_TODOREMOVE_TODOTOGGLE_TODO 常量字符串。 我们还定义了 AddTodoActionRemoveTodoActionToggleTodoAction 类型。

在 Angular2 应用中使用 Redux

在 Angular2 应用中使用 Redux 需要使用 provideStore 函数,它将 Store 提供给应用程序。

import { Component } from '@angular/core';
import { provideStore } from '@ngrx/store';
import { store } from './store';
import { initialState } from './state';
import { rootReducer, getTodoState } from './reducers';
import { TodoListComponent } from './todo-list.component';

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Todo List</h2>
      <todo-list 
        [todos]="todos"
        (add)="handleAdd($event)"
        (remove)="handleRemove($event)"
        (toggle)="handleToggle($event)">
      </todo-list>
    </div>
  `,
  directives: [TodoListComponent],
  providers: [
    provideStore({ todo: rootReducer }, { todo: initialState })
  ]
})
export class AppComponent {
  todos: Observable<any>;

  constructor(private _store: Store<AppState>) {}

  ngOnInit() {
    this.todos = this._store.select(getTodoState);
  }

  handleAdd(todo: any) {
    this._store.dispatch(new AddTodoAction(todo));
  }

  handleRemove(id: number) {
    this._store.dispatch(new RemoveTodoAction(id));
  }

  handleToggle(id: number) {
    this._store.dispatch(new ToggleTodoAction(id));
  }
}

在这里,我们传递一个 rootReducer 和初始状态对象。 我们创建一个 todos 的变量,它是从 Store 中选择的值。 我们处理 handleAddhandleTogglehandleRemove 的事件,并使用 store 的 dispatch 方法分别分派操作。

总结

在本文中,我们了解了 Redux 的基本原则,如何使用 Redux 在 Angular2 应用程序中管理应用程序状态。 我们还学习了如何创建 Redux Store,Reducer 和操作,以及如何将 Store 注入到我们的 Angular2 应用程序中。

感谢您阅读本文。 我们希望您现在能够使用 Redux 来管理 Angular2 应用程序中的状态!

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6592b1cceb4cecbf2d77231e


纠错反馈