[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>
);
;
showSuccess
与 showError
具有排他性,二者只会渲染一个。并且 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 的封装