redux的模块化

171 阅读1分钟

仓库模块化

在大型应用中,将 Redux 的逻辑模块化是非常重要的,这有助于保持代码的组织性和可维护性。模块化的方式可以通过拆分 reducers来实现。

拆分 reducers

将一个大的 reducer 拆分成多个小的 reducers,然后使用 combineReducers 将它们组合在一起。

目录结构:

/src 
    /store
        /auth.js
        /todos.js 
        /index.js 
   /App.js
// src/store/auth.js
const initialState = {
    user: null,
    isAuthenticated: false
};
const authReducer = (state = initialState, action) => {
    switch (action.type) {
        case 'LOGIN':
            state.isAuthenticated = true;
            state.user = action.payload.user;
            break;
        case 'LOGOUT':
            state.isAuthenticated = false;
            state.user = null;
            break;
        default:
            break;
    }
    // 返回的新的状态state需要深拷贝,这样的目的是解除对原来的state状态的引用
    state = JSON.parse(JSON.stringify(state))
    // 最后reducer方法必须返回处理后的新的状态state
    return state;
};

export default authReducer;
// src/store/todos.js
const initialState = {
    todos: []
};

const todosReducer = (state = initialState, action) => {
    switch (action.type) {
        case 'ADD_TODO':
            return {
                ...state,
                todos: [
                    ...state.todos,
                    {
                        id: Date.now(),
                        text: action.payload.text,
                        completed: false
                    }
                ]
            };
        case 'TOGGLE_TODO':
            return {
                ...state,
                todos: state.todos.map(todo =>
                    todo.id === action.payload.id ? { ...todo, completed: !todo.completed } : todo
                )
            };
        default:
            return { ...state };
    }
};

export default todosReducer;
// src/store/index.js
import { legacy_createStore as createStore, combineReducers } from 'redux'
import authReducer from './auth.js';
import todosReducer from './todos.js';
// 使用 combineReducers将authReducer和todosReducer组合在一起
const rootReducer = combineReducers({
    auth: authReducer,
    todos: todosReducer
})
// 创建 Store,调用redux的legacy_createStore来创建store数据仓库
let store = createStore(rootReducer);
export default store; // 将创建的仓库暴露出去

组件中使用模块化的仓库

// main.jsx
import { createRoot } from 'react-dom/client' // 用于渲染页面的
import React from 'react' // 用于创建组件的
import { Provider } from 'react-redux'; // 引入react-redux的Provider组件,然后用这个组件包裹App组件完成react-redux的全局注册
import App from './App.jsx'
import store from './store/index.js';

createRoot(document.getElementById('root')).render(
    <Provider store={store}>
        <App></App>
    </Provider>
)
// App.jsx
import React from 'react';
import { useSelector, useDispatch,useStore } from 'react-redux'
export default function App(props) {
  const store = useStore();
  const todos = useSelector((state) => state.todos.todos);
  console.log(store.getState(),'state')
  const dispatch = useDispatch();

  const handleAddTodo = () => {
    dispatch({ type: "ADD_TODO", payload: { text: "New Todo" } });
  };

  const handleToggleTodo = (id) => {
    dispatch({ type: "TOGGLE_TODO", payload: { id } });
  };
  return (
    <div>
      <div>
        <h1>Todos</h1>
        <ul>
          {todos.map((todo) => (
            <li
              key={todo.id}
              style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}
              onClick={() => handleToggleTodo(todo.id)}
            >
              {todo.text}
            </li>
          ))}
        </ul>
        <button onClick={handleAddTodo}>添加事项</button>
      </div>
    </div>
  );
}

store就分模块了,取得时候需要先取模块:

image.png

2.gif