React@16.x(54)Redux@4.x(3)- reducer

发布于:2024-07-16 ⋅ 阅读:(130) ⋅ 点赞:(0)

1,特点

用于改变数据仓库 store 数据的函数

一个数据仓库,有且仅有一个 reducer。而通常情况下,一个工程只有一个仓库,所以也只有一个 reducer

1.1,调用时机

  1. 当创建 store 时,会调用一次,可利用这点来初始化状态。
  2. 通过 store.dispatch 分发 action 时,也会调用。

1.2,必须是纯函数

  1. 有利于测试和调试。
  2. 有利于还原数据。
  3. 有利于和 React 结合时做优化。

2,举例

目录

action
	-- userAction.js
	-- loginAction.js
reducer
	-- user.js
	-- login.js
	-- index.js
-- index.js

通常 actionreducer 中相同模块,命名也会相同。

2.1,action

// action/userAction.js
export const ADD_USER = Symbol("add_user");
export const DELETE_USER = Symbol("delete_user");
export const UPDATE_USER = Symbol("update_user");

export const createAddUserAction = (user) => ({
    type: ADD_USER,
    payload: user,
});
export const createDeleteUserAction = (id) => ({
    type: DELETE_USER,
    payload: id,
});

export const createUpdateUserAction = (id, newValue) => ({
    type: UPDATE_USER,
    payload: {
        ...newValue,
        id,
    },
});
// action/loginAction.js
export const LOGIN = Symbol("login");

export const createLoginAction = (user) => ({
    type: LOGIN,
    payload: user,
});

2.2,reducer

大型项目中,数据和操作都比较复杂。会对 reducer 进行细分方便管理。

// reducer/user.js
import { ADD_USER, DELETE_USER, UPDATE_USER } from "../action/userAction";

const initState = [
    { id: 1, name: "name1", age: 18 },
    { id: 2, name: "name2", age: 19 },
];

export default (state = initState, { type, payload }) => {
    switch (type) {
        case ADD_USER:
            return [...state, payload];
        case DELETE_USER:
            return state.filter((f) => f.id !== payload);
        case UPDATE_USER:
            return state.map((m) => (m.id === payload.id ? { ...m, ...payload } : m));
        default:
            return state;
    }
};
// reducer/login.js
import { LOGIN } from "../action/loginAction";

const initState = null;

export default (state = initState, { type, payload }) => {
    switch (type) {
        case LOGIN:
            return payload;
        default:
            return state;
    }
};

2.2.1,结合

而最终只有一个 reducer,会在创建 store 时传递。

// reducer/index.js
import loginReducer from "./login";
import userReducer from "./user";

export default (state = {}, action) => {
    const newState = {
        loginReducer: loginReducer(state.loginReducer, action),
        userReducer: userReducer(state.userReducer, action),
    };
    return newState;
};

// 指定为其他名称:
export default (state = {}, action) => {
    const newState = {
        a: loginReducer(state.a, action),
        b: userReducer(state.b, action),
    };
    return newState;
};

解释

初始化 store 时,会调用一次进行初始化,会将这个 newState 做为初始值保存。
所以之后分发指定 action 时,state.loginReducer 就是旧值

redux 提供了 combineReducers,专门用来结合 reducer,和上面的作用一样。

// 替换如下
export default combineReducers({
    loginReducer,
    userReducer
})

同时可以指定为其他名称:

export default combineReducers({
    a: loginReducer,
    b: userReducer
})

2.3,index.js 使用

import { createStore } from "redux";
import reducer from "./reducer";
import { createAddUserAction, createUpdateUserAction, createDeleteUserAction } from "./action/userAction";

const store = createStore(reducer);
console.log(store.getState());

store.dispatch(createAddUserAction({ id: 3, name: "name3", age: 20 }));
console.log(store.getState());

store.dispatch(createUpdateUserAction(2, { name: "name22" }));
console.log(store.getState());

store.dispatch(createDeleteUserAction(1));
console.log(store.getState());

以上。


网站公告

今日签到

点亮在社区的每一天
去签到