@ccreator/mirror
v4.0.1
Published
redux state management powered by react-redux and @reduxjs/toolkit
Readme
Mirror 4.x
基于 react-redux + @reduxjs/toolkit 的 @ccreator/mirror 4.x 实现。
开发
npm install
npm run dev构建
npm run buildAPI
model(source)createStore()actionshook(callback)unhook(callback)getState()getModelState(modelName)hasModel(modelName)getModelNames()useModel(modelName, selector?, equalityFn?)defaults(opts)toReducers()debug(content, type?, color?)
Installation
# Install the library
npm i @ccreator/mirror
# or
yarn add @ccreator/mirrorUsage
1. Define Model
Note: When a model is loaded, set, reset and get methods are automatically added. Please do not add these methods to the model, otherwise they will be overwritten.
// src/models/demo.js
import { actions } from '@ccreator/mirror';
export default {
// Model name
name: 'demo',
// Model state
state: { books: [] },
// Synchronous methods
reducers: {
// Usage: actions.demo.addBook({ name: 'Bookname', author: 'Author' });
addBook(state, payload) {
const { books } = state;
books.push(payload);
return { ...state, books: [...books] };
}
},
// Asynchronous methods
effects: {
// Usage: actions.demo.fetchList({ author: 'Author' });
async fetchList(payload, getState) {
// getState() gets all state data
// console.log(getState());
const resp = await fetch(`/books?author=${payload.author}`);
const books = await resp.json();
actions.demo.set({ books });
}
},
}2. Initialize State Store
// store.js
import mirror from '@ccreator/mirror';
import app from './models/app';
import demo from './models/demo';
// 1. Load models
mirror.model(app);
mirror.model(demo);
// Try to split models into separate files
mirror.model({
name: 'loading',
state: 0,
reducers: {... ...}
});
// 2. Create data store
const store = mirror.createStore();
export default store;3. Inject State Store
// index.js
import React from 'react'
import ReactDOM from 'react-dom/client'
import mirror, { Provider } from '@ccreator/mirror';
import App from './App'
import store from './store';
// Action execution callback hook
mirror.hook(console.log)
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
)
4. Use Model State
Approach 1: Use hooks to access state (recommended)
const App = () => {
const { author, price } = useSelector((state) => state.book);
// or
const author = useSelector((state) => state.book.author);
const price = useSelector((state) => state.book.price);
... ...
}Approach 2: Use connect to map state to components
const App = ({ author, price, xxx }) => {
... ...
}
function dispatch({ book, xxx }) {
return {
author: book.author,
price: book.price,
xxx,
};
}
export default connect(dispatch)(App);Dynamic Model Loading
- Note: Models must be loaded first before calling model actions, otherwise actions.{model}.{action} will throw null value exceptions
- Note: If using React.lazy to load components, it's recommended to use approach 1 for business module splitting
- Note: Keep model names unique to prevent model properties and action methods from being overwritten
import React from 'react';
import mirror, { actions, connect } from '@ccreator/mirror';
import model from './user';
import get from 'lodash/get';
// Approach 1: Dynamic loading with React.lazy
mirror.model(model);
const Main = ({ page, dataSource }) => {
React.useEffect(() => {
// Approach 2: Dynamic loading within component
// mirror.model(model);
const temp = actions.user.get('page');
console.log(temp);
actions.user.set({ page: { index: 100, size: 1024 } });
}, []);
return <>{JSON.stringify({ page, dataSource })}</>;
};
function dispatch({ user }) {
// Note: When user model is not loaded, user is undefined, use lodash.get to prevent null value exceptions
return {
page: {
index: get(user, 'page.index', 1),
size: get(user, 'page.size', 10)
},
dataSource: user?.dataSource,
};
}
export default connect(dispatch)(Main);Updates
2026-05-08
- Reimplemented all APIs
- Upgraded dependencies and build tooling
2026-02-04
- export useModel
2025-12-01
- export useSelector and useStore
2024-07-20
- Implemented dynamic model loading for easier code splitting
- Updated dependencies
2023-01-17
- Removed react-router-dom dependency
- Modified initialization to support React 18.x
- Removed routing-related code and optimized code structure
2021-12-09
- Upgraded react-router-dom
- Removed react-router-redux
- Added export declarations for Router (HashRouter), BrowserRouter, MemoryRouter and other components
- Changed route navigation to actions.route.push() and actions.route.replace()
- Added default set, reset and get methods to models
- Allowed model reloading for on-demand loading scenarios
- Models now use state for initial state values
