State Management in React: Redux, Mobx, and Clean-State
The article compares traditional React state‑management solutions—Redux’s single‑store with extra libraries and potential re‑renders, and MobX’s fine‑grained but class‑based approach—against the lightweight, hook‑driven Clean‑State library, which avoids providers, reduces bundle size, and offers precise module‑level updates for large and consumer applications.
React has evolved through many versions, with state management approaches like Redux (Flux) and Mobx (reactive). After Hooks introduced in v16.8, new possibilities arise.
In large projects, UI fragmentation leads to scattered state, increasing entropy. Centralized state is recommended.
1. Redux stores state in a single store, updates via dispatch and reducers. However, it introduces extra libraries (react-redux, redux-thunk, redux-saga) increasing bundle size and learning cost, and can cause unnecessary re-renders because dispatch triggers top‑level setState.
// Provider injection
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import App from './App';
const rootElement = document.getElementById('root');
ReactDOM.render(
,
rootElement
);
// connect usage
import { connect } from 'react-redux';
import { increment, decrement, reset } from './actionCreators';
const mapStateToProps = (state) => ({
counter: state.counter,
});
const mapDispatchToProps = { increment, decrement, reset };
export default connect(mapStateToProps, mapDispatchToProps)(Counter);2. Mobx provides fine‑grained updates but relies on class‑based observable state and lacks centralization, making it less suitable for modern functional React.
// Observable state with Mobx
import { decorate, observable } from "mobx";
class TodoList {
@observable todos = [];
@computed get unfinishedTodoCount() {
return this.todos.filter(todo => !todo.finished).length;
}
}
// Observer component
import React, { Component } from 'react';
import { observer } from 'mobx-react';
@observer
class TodoListView extends Component {
render() {
return (
{this.props.todoList.todos.map(todo => (
))}
Tasks left: {this.props.todoList.unfinishedTodoCount}
);
}
}3. Clean‑State is a lightweight state‑management library built on top of React Hooks. It avoids Provider injection and variable lifting, enabling module‑level precise updates.
Key concepts:
Modules are defined by a state object, reducers, and effects.
Modules are registered via a bootstrap function that returns useModule and dispatch .
Modules can be mixed in to share common reducers.
Debugging is supported through a Redux‑devtool plugin.
// modules/user.js
const state = { name: 'test' };
const user = {
state,
reducers: {
setName({ payload, state }) {
return { ...state, ...payload };
},
},
effects: {
async fetchNameAndSet({ dispatch }) {
const name = await Promise.resolve('fetch_name');
dispatch.user.setName({ name });
},
},
};
export default user;
// modules/index.js
import user from './user';
import bootstrap from 'clean-state';
const modules = { user };
export const { useModule, dispatch } = bootstrap(modules);Usage example:
// page.js
import { useCallback } from 'react';
import { useModule, dispatch } from './modules';
function App() {
const { user } = useModule('user');
const onChange = useCallback(e => {
const { target } = e;
dispatch.user.setName({ name: target.value });
}, []);
const onClick = useCallback(() => {
dispatch.user.fetchNameAndSet();
}, []);
return (
name: {user.name}
Modify name:
Get name
);
}
export default App;Clean‑State promotes a minimalist approach, making state management easier for both large B‑side projects and consumer‑facing C‑side applications.
Tencent Cloud Developer
Official Tencent Cloud community account that brings together developers, shares practical tech insights, and fosters an influential tech exchange community.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.