仓库模块化
在大型应用中,将 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就分模块了,取得时候需要先取模块: