1. 程式人生 > 其它 >React useContext + useReducer 實現 Hooks 狀態管理功能

React useContext + useReducer 實現 Hooks 狀態管理功能

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> ); } export
default 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