React Hook中提供的 useContext 、 useReducer 以及 context API可以實(shí)現(xiàn)類redux的狀態(tài)管理功能,具體API的使用方法見官方文檔,這里結(jié)合 TypeScript 演示如何進(jìn)行組件的狀態(tài)管理
首先創(chuàng)建共享數(shù)據(jù)的Store組件 BgStore.js
import * as React from 'react';
interface IState { // 共享數(shù)據(jù)結(jié)構(gòu)
background: string;
}
interface IAction { // dispatch派發(fā)的action結(jié)構(gòu)
type: string;
value: string;
}
export interface IStore { // 由React.createContext所創(chuàng)建的store的數(shù)據(jù)機(jī)構(gòu),這里與BgContext.Provider 組件上的 value 是相對(duì)應(yīng)的
state: {
background: string
};
dispatch?: React.Dispatch<IAction>;
}
export const BgContext = React.createContext<IStore>({
state: {
background: '#eee'
}
});
const reducer: React.Reducer<IState, IAction> = (state, action) => {
switch (action.type) {
case 'UPDATE_BG':
return {...state, background: action.value};
default:
return state;
}
};
export const BgSore: React.FC = ({children}) => {
const [state, dispatch] = React.useReducer(reducer, {background: '#eee'}); // 創(chuàng)建reducer
return (
<BgContext.Provider value={{state, dispatch}}>
{children}
</BgContext.Provider>
);
};
建立根視圖 Index
import * as React from 'react';
import { BgSore } from './store/BgStore';
import Content from './components/Content';
import Buttons from './components/Buttons';
import GetState from './components/GetState'; // class component
const MokeRedux: React.FC= () => {
return (
<BgSore>
<Content />
<Buttons />
<GetState />
</BgSore>
);
};
export default MokeRedux;
建立子組件 Content.js
import * as React from 'react';
import { BgContext, IStore } from '../store/BgStore';
const Content: React.FC = () => {
const store: IStore = React.useContext(BgContext); // 通過useContext獲取共享的信息
return (
<div style={store.state}>background: {store.state.background}</div>
);
};
export default Content;
建立操作背景顏色變換的子組件 Buttons.js
import * as React from 'react';
import { Button } from 'antd';
import { BgContext, IStore } from '../store/BgStore';
const Buttons: React.FC = () => {
const store: IStore = React.useContext(BgContext);
const handleClickBlue = () => {
store.dispatch!({ // 這里推斷dispatch是一定存在的,因?yàn)樵?BgContext.Provider 組件中的 value={{state, dispatch}}>
// 之所以添加感嘆號(hào)是因?yàn)樵贗Store接口中,將dispatch設(shè)置為了可選屬性
type: 'UPDATE_BG',
value: 'blue'
});
};
const handleClickOrange = () => {
store.dispatch!({
type: 'UPDATE_BG',
value: 'orange'
});
};
return (
<>
<Button type="primary" onClick={handleClickBlue}>Update blue</Button>
<Button type="primary" onClick={handleClickOrange}>Update orange</Button>
</>
);
};
export default Buttons;
class component獲取共享數(shù)據(jù) GetState.js
import * as React from 'react';
import { BgContext, IStore} from '../store/BgStore';
interface IState {
name: string;
}
class GetState extends React.Component<{}, IState> {
public state = {
name: 'test'
};
public render() {
return (
<BgContext.Consumer>
{(props: IStore) => {
return (
<div>
<p>{props.state.background}</p>
<span>{this.state.name}</span>
</div>
);
}}
</BgContext.Consumer>
)
}
}
export default GetState;
這樣就簡(jiǎn)單實(shí)現(xiàn)了一個(gè)跨組件狀態(tài)管理的功能