redux核心API

redux是什么

Redux 是一个独立的js状态管理库,非React内容之一

为什么要使用redux

Redux本身是MVVM渐进式框架,M(数据模型) - V(视图) - VM(虚拟模型)

核心概念

  • state
  • reducer
  • store
  • action

state对象

通常我们会把应用中的数据存储到一个对象树中 进行统一管理,我们把这个位置称为: state

state 是只读的

这里需要注意的是,为了保证数据状态的可维护性和测试,不推荐直接修改state中的原数据

通过纯函数修改 state

  • 什么是纯函数

纯函数 – 函数式编程的一种概念

  1. 相同的输入永远返回相同的输出
  2. 不修改函数的输入值
  3. 不依赖外部环境状态
  4. 无任何副作用 (例如:异步请求以及定时器造成的问题)

使用纯函数的好处

  1. 便于测试
  2. 有利于重构

action 对象

  • 我们对state 的修改是通过reducer 纯函数来进行的,同时通过传入的 action 来执行具体的操作

  • action 是一个对象

  • type 属性: 表示要进行操作的动作类型, 增删改查。。。。

  • payload属性: 操作 state 的同时传入的数据

  • 但是这里需要注意的是,我们不直接去调用Reducer函数,而是通过Store对象提供的dispatch方法来调用

Store 对象 (负责存储的仓库)

  • 为了对 state, reducer, action,进行统一的管理和维护,我们需要创建一个Store对象(仓库)

redus 三大原则

  • 单一数据源: 整个应用的state 被储存在一棵 object tree中,并且这个object tree 只存在于唯一的store中

  • State 是只读的,唯一改变state的方法就是触发 action,action是一个用于描述已发生事件的普通对象

  • 使用纯函数来进行修改

如何使用

1. 安装

npm i redux

2. 引入

import { createStore } from 'redux';

3. 创建一个仓库,参数为一个纯函数

let store = createStore(reducer);

4. reducer纯函数

因为state的值可读不可写,所以需要一个纯函数去修改内部的值
这里给state加了默认值,可以不加

function reducer(state = {
    name: "电影院",
    age: 20
}, action) {
    return state;
};

输出仓库看浏览器反馈

console.log(store);

在这里插入图片描述

dispatch

dispatch: ƒ dispatch(action) —— 发起一次修改 (同步方法,立即执行)

	action:{
		type: "做了什么修改"  --必填
	}

getState

 getState: ƒ getState() —— 获取状态

replaceReducer

replaceReducer: ƒ replaceReducer(nextReducer) —— 替换掉 reducer

subscribe

subscribe: ƒ subscribe(listener) —— 监听状态的修改

使用getState

console.log(store.getState());

浏览器反馈
在这里插入图片描述

使用dispatch

使用dispatch发起1次修改后在获取状态

function reducer(state = {
    name: "电影院",
    age: 20
}, action) {
    // 不加这行注释的话,switch...case 会提示不是期望默认值,不过不影响,加不加无所谓
    // eslint-disable-next-line
    switch (action.type) {
        case 'edit_name':
            return {
                ...state,
                name: action.name
            }
    }
    return state;
};

...

store.dispatch({
    type: "edit_name",
    name: "健身房"
});

...

console.log(store.getState());

浏览器反馈
在这里插入图片描述
使用dispatch发起2次修改后在获取状态

function reducer(state = {
    name: "电影院",
    age: 20
}, action) {
    // 不加这行注释的话,switch...case 会提示不是期望默认值,不过不影响,加不加无所谓
    // eslint-disable-next-line
    switch (action.type) {
        case 'edit_name':
            return {
                ...state,
                name: action.name
            };
        case 'edit_age':
            return {
                ...state,
                age: action.age
            };
    }
    return state;
};

...

store.dispatch({
    type: "edit_name",
    name: "健身房"
});
store.dispatch({
    type: "edit_age",
    age: 2100
});

...

console.log(store.getState());

浏览器反馈
在这里插入图片描述
使用dispatch发起3次修改且有一个是新属性后在获取状态

function reducer(state = {
    name: "电影院",
    age: 20
}, action) {
    // 不加这行注释的话,switch...case 会提示不是期望默认值,不过不影响,加不加无所谓
    // eslint-disable-next-line
    switch (action.type) {
        case 'edit_name':
            return {
                ...state,
                name: action.name
            };
        case 'edit_age':
            return {
                ...state,
                age: action.age
            };
        case 'edit_time':
            return {
                ...state,
                time: action.time
            }
    }
    return state;
};

...

store.dispatch({
    type: "edit_name",
    name: "健身房"
});
store.dispatch({
    type: "edit_age",
    age: 2100
});
store.dispatch({
    type: "edit_time",
    time: '待定'
});

...

console.log(store.getState());

浏览器反馈
在这里插入图片描述

使用subscribe

state发送改变时触发

  • 参数为:出发时执行的回调函数
function reducer(state = {
    name: "电影院",
    age: 20
}, action) {
    // 不加这行注释的话,switch...case 会提示不是期望默认值,不过不影响,加不加无所谓
    // eslint-disable-next-line
    switch (action.type) {
        ...
    }
    return state;
};

store.subscribe(()=>{
    console.log(store.getState());
});

store.dispatch({
    ...
});

浏览器反馈
在这里插入图片描述

combineReducers

我们上边已经使用了dispatch发起修改成功了,但是可以看出代码量是很多的,而且很庞大。
所以我们换一种写法

import React from 'react';
import { createStore, combineReducers } from 'redux';

function index(state = { name: "首页" }, action) {
    // eslint-disable-next-line
    switch (action.type) {
        case 'edit_name':
            return {
                ...state,
                name: action.name
            }
    }
    return state
}

function list(state = { age: 20, time: "信息" }, action) {
    // eslint-disable-next-line
    switch (action.type) {
        case 'edit_age':
            return {
                ...state,
                age: action.age
            }
        case 'edit_time':
            return {
                ...state,
                time: action.time
            }
    }
    return state
}

function reducer(state = {}, action) {
    return {
        index: index(state.index, action),
        list: list(state.list, action)
    }
}

let store = createStore(reducer);

store.subscribe(() => {
    console.log(store.getState())
})

store.dispatch({
    type: "edit_name",
    name: "哈哈哈"
})
store.dispatch({
    type: "edit_age",
    age: 2100
})
store.dispatch({
    type: "edit_time",
    time: "待定"
})


function App() {
    return (<div>
        123
    </div>)
}

export default App

浏览器反馈
在这里插入图片描述
但是这里还没有更简洁,可以把reducer这个函数换成下边这种写法

let reducer = combineReducers({
    index,
    list
});

参数: 传入一个对象,这个对象的属性中,就是要合并的reducer

注意点: 对象的属性名,要和函数名相同

浏览器反馈
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值