我的react开发笔记 - 前端与后台的交互,以及相关异常判断与动态交互的实现
登录界面中的“登录”按钮作为前端和后端交互的关键,涉及许多逻辑判断,比如 登录表单的验证、前端POST数据的发送、异常捕获与处理等。本文介绍了在react框架下,如何设计一个简单且整的”登录“过程。
-- By Brisk
一、构建页面中的元素
页面中的元素包括用户输入框和”登录“按钮,如下所示:
接下来,编写点击按钮的相关代码
二、登录按钮UI的变化
当点击登录按钮时,希望的外观实现两种变化:1)按钮变为不可选,即disabled = true;2)有动态展示的效果,告知用户正在和后端交互。
这里我们直接使用ant design中提供的加载中状态按钮,即通过修改Button中的loading属性来实现。当loading属性为true时,按钮即不可选且展示动态加载效果。
希望实现这样的效果,则需要在按钮的点击事件中,动态的修改Button中loading属性的值。这里需要使用state变量。简单来说,通过state变量的变化,可以实现DOM的变化,而无需直接操作DOM。
注:在函数组件中,需要使用state变量实现和OM元素的“绑定”,函数中的一般变量的变化,不会导致DOM的变化。
首先定义一个state变量:
const [btnLoadingFlag, setbtnLoadingFlag] = useState(false);
其中,btnLoadingFlag是变量名称,setbtnLoadingFlag是对这个变量进行赋值的方法名,右边useState(false)表明该state变量的初值为false。
在函数组件中如下所示直接引用该state变量。这样函数组件的DOM就和这个变量实现了“绑定”。
<Button style={{width: '100%'}} type="primary" onClick={Submit} size='large' htmlType="submit" loading={btnLoadingFlag}>登录</Button>
之后,就可以通过主动地修改state变量setbtnLoadingFlag的值,来实现对登录按钮UI的改变:
setbtnLoadingFlag(false) 或 setbtnLoadingFlag(true)
(参考资料:按钮 Button - Ant Design)
三、表单的验证
点击登录按钮后,第一步是进行表单的验证,即检查登录信息输入框中的内容是否完整。这里使用ant design提供的表单验证API。
1. 定义用于表单引用的变量:
const loginFormRef = useRef(null)
2. 将该变量与Form绑定:
<Form labelCol={{ span: 4 }} wrapperCol={{ span: 16 }} size='large' name="login" onValuesChange={onValuesChange} ref={loginFormRef}>
之后,就可以使用loginFormRef这个变量进行一些和该Form相关的操作。
3. 调用validateFields方法,实现对表单的验证。该验证是异步操作,即validateFields实际上是一个Promise。为了代码阅读方便,这里使用await等待该异步操作完成再继续进行。
let values = await loginFormRef.current.validateFields()
注意,因为这里实际上是一个Promise,如果使用链式写法,需要在catch中编写相关的异常处理方法。这里因为使用了await,因此使用try-catch将相关代码包围,并在该catch中编写相关异常处理方法。
相关详细介绍,可参阅之前的文章:
我的react开发笔记 - 基于antd的表单验证 以及 JavaScript中Promise对象的相关总结 - Brisk - 博客园 (cnblogs.com)
四. 与后台接口交互
前端工程的一个重要的功能就是和后台进行交互。在ASP .NET中,我们会使用jquery的AJAX,在vue中我们会使用axios。这里我们使用浏览器直接支持的fetch。这里举一个和后台进行POST交互的例子,其中后台是Springboot。
const userJOSN = {name: loginInfo.userId, password: loginInfo.password} let res = await fetch('http://localhost:8081/login', { method: 'POST', headers: {"Content-type": "application/json; charset=UTF-8"}, body: JSON.stringify(userJOSN), });
注意,这里fetch也是Promise,因此也使用了await等待该异步操作完成。
fetch返回的res,可以理解为只是一个响应,需要调用.json()方法来获取其中的data。该json方法也是一个Promise,因此需要使用await等待该异步操作完成。
// res只是一个 HTTP 响应,而不是真的 JSON。为了获取 JSON 的内容,需要使用 json() 方法(该方法返回一个将响应解析成 JSON 的 promise)。 let data = await res.json() console.log(data.code)
五. 异常处理与判断
上述验证与fetch因为使用了await,因此需要使用try-catch语句对其进行异常处理。在catch中需要对异常的类型进行判断,并且进行不同的处理。JS中定义了多种类型的异常,可以根据error的name属性进行区分。对于一些第三方自定义的异常,需要具体问题具体分析。