1. component in statusmanagement
in Reactin, component in statusmanagement is 最Basics statusmanagement方式, throughuseState Hook or this.state (classcomponent) 来managementcomponent in 部 status.
1.1 usinguseState Hook
function Counter() {
const [count, setCount] = useState(0);
const [name, setName] = useState('');
const handleIncrement = () => {
setCount(count + 1);
};
const handleNameChange = (e) => {
setName(e.target.value);
};
return (
<div>
<p>Count: {count}</p>
<button onClick={handleIncrement}>Increment</button>
<div>
<input type="text" value={name} onChange={handleNameChange} placeholder="Enter your name" />
<p>Hello, {name}!</p>
</div>
</div>
);
}
1.2 usingclasscomponent state
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0,
name: ''
};
}
handleIncrement = () => {
this.setState({ count: this.state.count + 1 });
};
handleNameChange = (e) => {
this.setState({ name: e.target.value });
};
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.handleIncrement}>Increment</button>
<div>
<input type="text" value={this.state.name} onChange={this.handleNameChange} placeholder="Enter your name" />
<p>Hello, {this.state.name}!</p>
</div>
</div>
);
}
}
2. Context APIstatusmanagement
Context API允许 in componenttreein共享status, 而无需throughprops逐层传递, 适用于inetc.规模 statusmanagement.
// creationContext
const UserContext = React.createContext();
// creationProvidercomponent
function UserProvider({ children }) {
const [user, setUser] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const login = async (email, password) => {
setIsLoading(true);
try {
// mockAPIrequest
const response = await fetch('https://api.example.com/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ email, password })
});
const data = await response.json();
setUser(data.user);
} catch (error) {
console.error('Login error:', error);
} finally {
setIsLoading(false);
}
};
const logout = () => {
setUser(null);
};
const value = {
user,
isLoading,
login,
logout
};
return (
<UserContext.Provider value={value}>
{children}
</UserContext.Provider>
);
}
// creation自定义Hook, 方便usingContext
function useUser() {
const context = useContext(UserContext);
if (!context) {
throw new Error('useUser must be used within a UserProvider');
}
return context;
}
// usingContext component
function LoginButton() {
const { user, login, logout, isLoading } = useUser();
const handleLogin = () => {
login('example@example.com', 'password123');
};
if (isLoading) {
return <button disabled>Loading...</button>;
}
if (user) {
return (<
>
<p>Welcome, {user.name}!</p>
<button onClick={logout}>Logout</button>
</>
);
}
return <button onClick={handleLogin}>Login</button>;
}
// in AppcomponentinusingProvider
function App() {
return (
<UserProvider>
<div>
<LoginButton />
</div>
</UserProvider>
);
}
提示
Context API适用于共享全局status, such asuserinformation, 主题设置etc..
3. Reduxstatusmanagement
Redux is a 独立 statusmanagementlibrary, 适用于 big 型 complex application statusmanagement.
3.1 Reduxcore concepts
- Store: storeapplication 所 has status
- Action: describesstatus变化 object
- Reducer: 根据Actionupdatestatus function
- Dispatch: 触发Action method
- Selector: from Storein获取status method
3.2 usingRedux Toolkit
Redux Toolkit is 官方推荐 Reduxtool集, 简化了Redux using.
// installationRedux Toolkit
// npm install @reduxjs/toolkit react-redux
// creationSlice
import { createSlice } from '@reduxjs/toolkit';
const counterSlice = createSlice({
name: 'counter',
initialState: {
value: 0
},
reducers: {
increment: (state) => {
state.value += 1;
},
decrement: (state) => {
state.value -= 1;
},
incrementByAmount: (state, action) => {
state.value += action.payload;
}
}
});
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;
// creationStore
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './counterSlice';
const store = configureStore({
reducer: {
counter: counterReducer
}
});
export default store;
// in AppcomponentinusingProvider
import { Provider } from 'react-redux';
import store from './store';
function App() {
return (
<Provider store={store}>
<Counter />
</Provider>
);
}
// usingReduxstatus component
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement, incrementByAmount } from './counterSlice';
function Counter() {
const count = useSelector((state) => state.counter.value);
const dispatch = useDispatch();
return (
<div>
<p>Count: {count}</p>
<button onClick={() => dispatch(increment())}>Increment</button>
<button onClick={() => dispatch(decrement())}>Decrement</button>
<button onClick={() => dispatch(incrementByAmount(5))}>Increment by 5</button>
</div>
);
}
4. MobXstatusmanagement
MobX is 另一个流行 statusmanagementlibrary, usingresponse式programmingmodel.
// installationMobX
// npm install mobx mobx-react-lite
// creationStore
import { makeObservable, observable, action } from 'mobx';
class CounterStore {
count = 0;
constructor() {
makeObservable(this, {
count: observable,
increment: action,
decrement: action,
incrementByAmount: action
});
}
increment = () => {
this.count += 1;
};
decrement = () => {
this.count -= 1;
};
incrementByAmount = (amount) => {
this.count += amount;
};
}
export const counterStore = new CounterStore();
// usingMobXstatus component
import { observer } from 'mobx-react-lite';
import { counterStore } from './counterStore';
const Counter = observer(() => {
return (
<div>
<p>Count: {counterStore.count}</p>
<button onClick={counterStore.increment}>Increment</button>
<button onClick={counterStore.decrement}>Decrement</button>
<button onClick={() => counterStore.incrementByAmount(5)}>Increment by 5</button>
</div>
);
});
export default Counter;
5. statusmanagementsolutions选择
选择合适 statusmanagementsolutions取决于application 规模 and complexity:
| solutions | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| component in status | simple component, status只 in component in 部using | simple 易用, 无需额 out 依赖 | 不适用于跨componentstatus共享 |
| Context API | inetc.规模application, 共享 few 量全局status | React in 置, 无需额 out 依赖, using simple | 不适用于 complex status逻辑, performance可能不佳 |
| Redux | big 型 complex application, status逻辑 complex | statusmanagement集in, 易于debug and test | Learning曲线陡峭, 样板code many |
| MobX | inetc.规模application, response式programmingmodel | Learning曲线平缓, performance good | response式model可能导致不可预测 behavior |
6. best practices
- 优先usingcomponent in status, 只 in 必要时才using全局statusmanagement
- 保持status尽可能 simple , 避免嵌套过深
- using不可变dataupdatestatus, 避免直接modifystatus
- 将status逻辑 and UIcomponent分离
- for complex status添加TypeScriptclass型定义
- 定期clean不再需要 status
练习 1: usingContext APImanagement主题status
- creation一个ThemeContext, package含dark and light两种主题
- implementation主题切换functions
- in many 个componentinusing主题status
练习 2: usingRedux Toolkitmanagement计数器status
- creation一个计数器Slice
- configurationRedux Store
- implementation计数器component, package含增减functions