React useContext + useReducer 實現 Hooks 狀態管理功能
阿新 • • 發佈:2022-04-11
App.tsx
import { useReducer } from "react"; import { BrowserRouter, Switch } from 'react-router-dom'; import { renderRoutes } from "react-router-config"; import routes from "./router"; import { IUser, IReducerAction } from '@/common/types/interface' import { UserContext } from '@/store/user' function App() {const userReducer = (state: IUser, action: IReducerAction) => { switch (action.type) { case 'updata': return { ...state, ...action.params } default: return state } } const userStorage = sessionStorage.getItem('userInfo') || '{}' const initialUserState = JSON.parse(userStorage)const [store, dispatch] = useReducer(userReducer, initialUserState) return ( <UserContext.Provider value={{store, dispatch}}> <BrowserRouter> <Switch> { renderRoutes(routes) } </Switch> </BrowserRouter> </UserContext.Provider> ); } exportdefault App;
建立createContext(@/store/user)import { createContext } from "react"; // import { ICreateContext } from '@/common/types/interface' interface ICreateContext { store: any, dispatch: any } export const UserContext = createContext<ICreateContext>({ store: '', dispatch: '' });
在登入時獲取介面返回的資料,並更新到 store 中
import React, {useContext} from "react"; import { LoginWrapper, LoginContainer } from './styled' import { Form, Input, Button, message } from 'antd'; import { login } from '@/api/login' import { UserContext } from '@/store/user' interface ILogin { userName: string; password: string; } const Login: React.FC = (props:any) => { const { dispatch } = useContext(UserContext) const onFinish = async (form: ILogin) => { try { const res:any = await login(form) message.success(res.message); sessionStorage.setItem('userInfo', JSON.stringify(res.data)) dispatch({ type: 'updata', params: res.data }) setTimeout(() => { props.history.push('/home') }, 1000) } catch (error) { } }; const onFinishFailed = (errorInfo: any) => { console.log('Failed:', errorInfo); }; return ( <LoginWrapper> <LoginContainer> <h2>登入</h2> <Form name="basic" labelCol={{ span: 6 }} wrapperCol={{ span: 18 }} initialValues={{ userName: 'Fengchengzhi', password: '123456' }} onFinish={onFinish} onFinishFailed={onFinishFailed} autoComplete="off" > <Form.Item label="Username" name="userName" rules={[{ required: true, message: 'Please input your username!' }]} > <Input /> </Form.Item> <Form.Item label="Password" name="password" rules={[{ required: true, message: 'Please input your password!' }]} > <Input.Password /> </Form.Item> <Form.Item wrapperCol={{ offset: 10, span: 14 }}> <Button type="primary" htmlType="submit"> Submit </Button> </Form.Item> </Form> </LoginContainer> </LoginWrapper> ) } export default Login
獲取 store 資料並展示
import React, { useContext } from "react"; import { HeaderWrapper } from './styled' import { UserContext } from '../../store/user' const HeaderComps: React.FC = () => { const { store: userInfo } = useContext(UserContext) return ( <HeaderWrapper className="header-wrapper"> 使用者姓名:{ userInfo.userName } </HeaderWrapper> ) } export default HeaderComps