• 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 { UserContext } from '@/store/user';
    import { IUser, IReducerAction } from '@/common/types/interface';
    import { UserStoreActionType } from '@/common/types/enum';

    function App() {
      const myUserReducer = (state: IUser, action: IReducerAction): IUser => {
        const { type } = action;
        switch (type) {
          case UserStoreActionType.SetData:
            localStorage.setItem('userInfo', JSON.stringify({ ...state, ...action.params }));
            return { ...state, ...action.params };
          default:
            return state;
        }
      };
      const userStorage = localStorage.getItem('userInfo') || '';
      const initialUserState = userStorage ? JSON.parse(userStorage) : null;
      const [store, dispatch] = useReducer(myUserReducer, 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 { IUser, IReducerAction } from '@/common/types/interface';
    // import { UserStoreActionType } from '@/common/types/enum';

    interface ICreateContext {
      store: IUser;
      dispatch: (params: IReducerAction) => void;
    }
    export const UserContext = createContext<ICreateContext>({
      store: {
        userName: '',
        sex: '',
        age: '',
        mobile: '',
        mailbox: '',
        password: ''
      },
      dispatch: () => {},
    });

    在登录时获取接口返回的数据,并更新到  store 中

    import React, { useContext, useEffect } from 'react';
    import { useHistory } from 'react-router-dom';
    import { LoginWrapper, LoginContainer } from './styled';
    import { Form, Input, Button, message } from 'antd';
    import { login } from '@/api/login';
    import { UserContext } from '@/store/user';
    import { UserStoreActionType } from '@/common/types/enum';
    import { useRequest } from 'ahooks';
    import { useForm } from 'antd/lib/form/Form';

    interface ILogin {
      userName: string;
      password: string;
    }

    const Login: React.FC = () => {
      const history = useHistory();
      const { dispatch } = useContext(UserContext);
      const [form] = useForm<ILogin>();

      useEffect(() => {
        // 设置默认参数
        form.setFieldsValue({ userName: 'Fengchengzhi', password: '123456' });
      }, []);

      const { loading, run } = useRequest((formVal: ILogin) => login(formVal), {
        manual: true,
        onSuccess: (res) => {
          message.success((res as any).message);
          dispatch({
            type: UserStoreActionType.SetData,
            params: res.data,
          });
          setTimeout(() => {
            history.push('/home');
          }, 1000);
        }
      });

      const onFinish = (formData: ILogin) => {
        run(formData);
      };

      const onFinishFailed = () => {
        // throw new Error('请填写完整信息!');
      };

      // 注册
      const onRegister = () => {
        history.push('/register');
      };

      return (
        <LoginWrapper>
          <LoginContainer>
            <h2>登录</h2>
            <Form
              name="basic"
              labelCol={{ span: 6 }}
              wrapperCol={{ span: 18 }}
              form={form}
              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"
                  loading={loading}
                  htmlType="submit"
                >
                  登录
                </Button>
              </Form.Item>
              <Form.Item wrapperCol={{ offset: 10, span: 14 }}>
                <Button type="link" onClick={onRegister}>
                  注册
                </Button>
              </Form.Item>
            </Form>
          </LoginContainer>
        </LoginWrapper>
      );
    };

    export default Login;

    UserStoreActionType 

    export enum UserStoreActionType {
      SetData = 'SET_DATA',
    }

    获取 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
  • 相关阅读:
    Python深拷贝和浅拷贝解析
    python中count函数的用法
    Jenkins + gitlab + maven 自动打包部署项目
    nio和bio得区别
    nginx负载均衡的5种策略
    接口测试常见bug
    接口自动化面试4
    pass 语句
    if 语句
    while循环
  • 原文地址:https://www.cnblogs.com/fczbk/p/16132310.html
Copyright © 2020-2023  润新知