[React 实战系列] 注册功能的优化

Posted GoldenaArcher

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[React 实战系列] 注册功能的优化相关的知识,希望对你有一定的参考价值。

之前已经实现的内容:

至上一篇为止,注册的基本功能已经实现了,但是用户注册了之后 UI 没有与用户实现有意义的互动,并且当用户回到注册页面的时候,基本的注册信息被持久化在页面上。

这一篇主要实现的目的就是对这些功能进行优化。

注册功能的优化

一般页面注册流程如下:

同时
同时
注册
注册成功
注册成功提示
注册失败
注册失败提示
清空表单
重置状态
离开页面

重置状态的目的是为了清空:

  • 注册成功信息
  • 注册失败信息
  • 用户注册信息

这样,当用户下一次打开注册页面时,之前提示的所有信息都会被重置。

获取注册状态

回顾一下在上一篇 注册功能的实现 中,注册功能的状态已经被定义好了:

// Auth状态中管理注册的逻辑
// loaded代表API是否调用成功
// success代表是否注册成功
// message代表的是错误信息
export interface AuthState 
  signup: 
    loaded: boolean;
    success: boolean;
    message: string;
  ;


// 根据interface去初始化状态
const initialState: AuthState = 
  signup: 
    loaded: false,
    success: false,
    message: '',
  ,
;

也就是说,只要能够获取注册的 store,就可以获取注册的状态。React Redux 封装了一个勾子函数 useSelector,通过 useSelector 就可以很方便的获取 React Redux 中的状态:

Signup.txs 中新增如下代码获取注册的状态:

// ...省略 import

const Signup = () => 
  // 获取 auth的状态
  // AppState, AuthState 是为了满足 TypeScript 中静态检查的需求
  // 如果不传值,TypeScript 会 complain 说
  // Property 'auto' does not exist on the 'DefaultRootState'
  const auth = useSelector<AppState, AuthState>((state) => state.auth);

  // ... 省略未修改代码
;

接下来注册页面的状态都可以通过 auth 去获得。

注册流程的优化

这一步会根据流程图去进行四个优化功能的实现:

  • 清空表单
  • 显示成功提示信息
  • 显示失败提示信息
  • 重置状态

而这些功能都需要通过监听 auth 状态的更改去实现,React 自身封装了 useEffect 生命周期钩子函数,可以监听状态变更从而进行 DOM 的操作。其功能类似于 class-based component 中的 componentDidUpdate() 生命周期方法。

useEffect 结构如下:

// ...省略 import

const Signup = () => 
  useEffect(() => 
    // 触发 effect
    effect;

    // 返回一个函数去做清理副作用
    return () => 
      cleanup;
    ;
    // 第二个参数会监听值的变化,如这里就会监听 `input` 的变化
  , [input]);
;

通过 useEffect 就可以去监听 auth 的变化,从而获悉登陆状态的变更。

清空表单

表单组件是 antd 提供的,表单状态的修改最简单的方式也是通过 antd 去管理,antd 的 Form 组件提供了 useForm 钩子函数去对表单的状态进行管理:

const Signup = () => 
  // antd官方用法
  const [form] = Form.useForm();

  // 通过 useEffect 去同时监听
  useEffect(() => 
    if (auth.signup.loaded && auth.signup.success) 
      form.resetFields();
    
    // 监听 auth 状态的变化去进行表单重置
  , [auth]);

  // 同时需要将 form 传入 Form 组件,使得 Form 组件知道状态的变更
  return (
    <Layout title="注册" subTitle=''>
      <Form form=form onFinish=onFinish>
        /* 忽略其他 */
      </Form>
    </Layout>
  );
;

显示成功提示信息

显示登录成功提示信息可以通过调用函数进行处理,这样不需要通过 useState 重新定义一个状态,也不需要在 useEffect 中进行副作用的管理:

const Signup = () => 
  const showSuccess = () => 
    if (auth.signup.loaded && auth.signup.success) 
      return (
        <Result
          key="signup-success"
          status="success"
          title="注册成功"
          extra=[
            <Button type="primary">
              <Link to="/signin">登录</Link>
            </Button>,
          ]
        />
      );
    
  ;

  return (
    <Layout title="注册" subTitle=''>
      showSuccess()
      <Form form=form onFinish=onFinish>
        /* 忽略其他 */
      </Form>
    </Layout>
  );
;

登录成功与表单重置的 Demo:

显示失败提示信息

失败的提示信息也可以通过同样的方法进行实现:

const Signup = () => 
  const showError = () => 
    if (auth.signup.loaded && !auth.signup.success) 
      return (
        <Result
          key="signup-fail"
          status="warning"
          title="注册失败"
          subTitle=auth.signup.message
        />
      );
    
  ;

  return (
    <Layout title="注册" subTitle=''>
      showSuccess()
      showError()
      <Form form=form onFinish=onFinish>
        /* 忽略其他 */
      </Form>
    </Layout>
  );
;

showSuccessshowError 具有排他性,二者只会渲染一个。并且 javascript 函数默认返回 undefined,没有进入 if 控制流程的话就会直接返回 undefined。

注册失败的 Demo:

重置状态

状态重置需要在组件卸载时使用,在 class-based component 中,可以使用 componentdidunmount 进行实现。在 functional component 中,同样可以通过 useEffect 去实现。

useEffect 第二个参数为空数组时,就会在组件 第一次渲染 以及 即将卸载 时进行调用,类似于 ComponentDidMount()componentWillUnmount()

const Signup = () => 
  // 省略其他
  useEffect(() => 
    // 如果这里有其他函数,将会在组件第一次渲染时调用

    // return 中的方法会在组件卸载时调用
    return () => 
      // 依旧使用 Redux 进行管理
      dispatch(resetSignup());
    ;
  , []);

  // 省略渲染部分
;

Redux 的流程与之前登录的功能类似。

  • action

    export interface SignupResetAction 
      type: typeof SIGNUP_RESET;
    
    
    export const resetSignup = () => (
      type: SIGNUP_RESET,
    );
    
  • reducer

export default function authReducer(
  state = initialState,
  action: AuthUnionType
) 
  switch (
    action.type
    // 省略其他
    case SIGNUP_RESET:
      return 
        ...state,
        // 重置成初始状态
        signup: 
          loaded: false,
          success: false,
          message: "",
        ,
      ;
  ) 
  

注册重置的 Demo:

鉴于这里使用的匿名模式,React Dev Tool 和 Redux Dev Tool 在匿名模式下不工作,所以这里通过检查 Redux Logger 去查看状态的变化。

可以看到,在 Redux Logger 中,prev state 中的 signup 的数据结构为:

signup: 
    loaded: true,
    success: true

而在 next state 中的 signup 的数据结构为:

signup: 
    loaded: false,
    success: false,
    message: ""

至此,注册的功能就完成了,下一篇会实现登录的功能。

以上是关于[React 实战系列] 注册功能的优化的主要内容,如果未能解决你的问题,请参考以下文章

[React 实战系列] 布局登录注册的页面实现及 Route 的封装

React系列实战篇:留言功能

React系列实战篇:留言功能

React 简书项目实战icon优化header

数学建模MATLAB应用实战系列(136)-优化算法:0-1背包算法(附MATLAB代码)

SpringCloud系列——nacos组件服务注册与发现功能实战