学习Redux第一天(基于angular的简易小demo-实现组件间通讯)


前言

最近项目临近结束,没多少工单要做,就开始自学Redux,打算使用redux做一个组件间通讯的demo


一、官方文档

Redux中文文档

二、Action Reducer Store

1.核心概念

  1. state中存储数据,但是不可以修改。
  2. 要想修改state中存储的数据,需要发起一个action,action主要用来描述发生了什么,它的定义也比较语义化,
  3. 而实现数据修改主要靠reducer,reducer将state与action关联起来,通过一个函数改变state树(接收一个旧的state与action,通过判断action.type执行相应的处理,返回一个新的state)。
    注意:当state变化时,需要返回全新的对象,而不是修改时传入的参数

2.快速上手

代码下载地址:https://github.com/fairyLiu-153/angular-redux

  1. npm install --save redux
  2. 这是一个非常简易的demo,但是对于理解利用redux来实现组件间通讯非常的有帮助。主要表现为:点击登录按钮,文字切换为hello Nancy! 点击退出按钮,文字切换为 请登录…
  3. 使用了三个组件,最外层父组件(蓝框),display组件(绿框),login组件(红框),点击按钮改变login的状态,display组件获取login状态来显示文字
    在这里插入图片描述
    在这里插入图片描述
  4. 文件目录如下(只需要看关于login的即可,to-do-list为下一个demo)
    在这里插入图片描述

代码如下(完整代码):
1.login.action.ts: 只有一个type:SET_IS_LOGIN,布尔型

import { Action, ActionCreator } from 'redux';


export interface SetIsLoginAction extends Action {
    login: boolean;
}

export const SET_IS_LOGIN = 'SET_IS_LOGIN';
export const setIsLogin: ActionCreator<SetIsLoginAction> = (login: boolean) => ({
    type: SET_IS_LOGIN,
    login

});

2.actions目录下index.ts:

import * as LoginActions from './login.action';
// import * as TodoListActions from './to-do-list.action';

export {
    LoginActions,
    //TodoListActions
}

3.login.reducer.ts:

import { SET_IS_LOGIN, SetIsLoginAction } from '../actions/login.action';
import { Reducer, Action } from 'redux';


export interface LoginState {
    login: boolean;
}

const initialState: LoginState = {
    login: false,
};

/*  reducer改变状态树: 接收旧的state和action,返回新的state
   (state, action)=> state
    当state变化时,需要返回全新的对象,而不是修改传入的参数
*/
export const LoginReducer = function (state = initialState, action: Action) {
    switch (action.type) {
        case SET_IS_LOGIN:
            const login = (action as SetIsLoginAction).login;
            return Object.assign({}, state, { login });
        default:
            return state;
    }
};

4.reducers目录下index.ts:

import { Reducer, combineReducers } from 'redux';
import { LoginState, LoginReducer } from './login.reducer';
export * from './login.reducer';
 //import { ToDosState, ToDosReducer } from './to-do-list.reducer';
 //export * from './to-do-list.reducer';




export interface AppState {
    login: LoginState;
    //toDoList: ToDosState;

}

export const rootReducer: Reducer<AppState> = combineReducers<AppState>({
    login: LoginReducer,
    //toDoList: ToDosReducer
});

5.redux.service.ts:

import { Injectable } from '@angular/core';
import { createStore, Store, Unsubscribe } from 'redux';
import { AppState, rootReducer} from './reducers';
import { LoginState } from './reducers/login.reducer';
import { ITodoItem, ToDosState } from './reducers/to-do-list.reducer';
import { TodoListActions, LoginActions } from './actions';


@Injectable({
  providedIn: 'root'
})
export class ReduxService {
  private store: Store<AppState>;
  private unsubscribe: Unsubscribe;
  constructor() {
    // 创建redux store 来存放应用的状态
    this.store = createStore(
      rootReducer
    );
  }

  // 读取状态
  getIsLogin(): boolean {
    const state: LoginState = this.store.getState().login;
    return state.login;

  }

  // 改变内部state -> dispatch一个action
  setIsLogin(login: boolean) {
    this.store.dispatch(LoginActions.setIsLogin(login));
  }

  // 订阅更新
  subscribeStore(readStateFun: () => void) {
    this.unsubscribe = this.store.subscribe(readStateFun);
  } 

6.display.component.html:

<h1>使用Redux实现组件通讯</h1>

<span *ngIf="login">hello Nancy!</span>
<span *ngIf="!login">请登录...</span>

7.display.component.ts:

import { Component, OnInit } from '@angular/core';
import { ReduxService } from 'src/app/redux/redux.service';

@Component({
  selector: 'app-display',
  templateUrl: './display.component.html',
  styleUrls: ['./display.component.scss']
})
export class DisplayComponent implements OnInit {

  login: boolean;

  constructor(
    private reduxService: ReduxService
  ) { }

  ngOnInit(): void {
    this.reduxService.subscribeStore(() => this.readState());
    this.readState();
  }

  readState() {
    this.login = this.reduxService.getIsLogin();

  }


}

8.login.component.html:

<div>
    <button (click)="login()">登录</button>
  </div>
  <div>
    <button (click)="logout()">退出</button>
  </div>

9.login.component.ts:

import { Component, OnInit } from '@angular/core';
import { ReduxService } from 'src/app/redux/redux.service';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {

  constructor(
    private reduxService: ReduxService
  ) { }

  ngOnInit(): void {
  }

  login() {
    this.reduxService.setIsLogin(true);
  }
  logout() {
    this.reduxService.setIsLogin(false);
  }

}

总结

提示:这个demo非常简易,总体只是对login的状态进行获取和设置,登录状态还是退出状态,但是完成之后会对redux有一个新的认识,懂得写redux的基本步骤,查阅相关资料几乎很多都是基于React的,现angular简易小demo可参考。(初学者)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值