React 结合 Rxjs 使用,管理数据

前言

在使用 React 过程中,我们需要对接口返回的数据进行数据的存储管理。比如用户数据在跨组件中的使用,当然,我们可以使用 localStorage 来管理该用户的信息,这个会在下一篇的文章中介绍,敬请期待~

本文,我们主打使用 Rxjs 来管理数据。

Rxjs 是什么

Rxjs 是一个用于处理异步事件的库,通过使用 observable 序列来编写异步和基于事件的程序,实际应用场景有把请求封装成 observable,通过一些基本的操作符,比如 mapfilter 等,将返回的数据处理并且捕获错误。比如我们之前讲解的 了解 Angular 开发的内容 – 服务 ServiceRxjs 中怎么处理和抓取错误。当然,Rxjs 还可以用来管理数据,在组件中传递数据~这是我们本文需要了解的内容。

安装 Rxjs

本文演示的项目,是通过 Create React App 创建,读者可以参考文章 Create React App 创建前端项目

“react” 版本为 “^18.2.0”

我们通过下面命令行安装依赖👇

npm install rxjs

截止发文,安装的版本为 "rxjs": "^7.8.0"

结合 React,使用 Rxjs

下面,我们以获取用户登陆的信息为例子,演示如何使用 rxjs 管理数据,在 vue 中同理~

PS angular-cli 项目中已经默认集成了 TypeScript 形式的 Rxjs,请参考 了解 Angular 开发的内容 – 服务 Service 写法使用

我们新建一个数据管理的 javascript 文件:

// src/service/data-manage.js

import { BehaviorSubject } from 'rxjs'; // 引入 BehaviorSubject; 它保存了发送给消费者的最新值
let userInfoSubject$ = new BehaviorSubject({});
// 获取用户的信息
export const getUserInfoData = () => {
  return userInfoSubject$.asObservable();
}
// 设置用户的信息
export const setUserInfoData = () => {
  userInfoSubject$.next(data);
}

我们在登陆页面,当用户成功登陆的时候,设置 userInfoSubject$ 的值:

// src/pages/Login.js
// 登陆页面
import React, { useState } from 'react';
import { Form, Input, Button } from 'react-vant'; // 引入了 react vant 移动端框架
import { setUserInfoData } from '../service/data-manage';
import { useNavigate } from 'react-router-dom'; // 路由导航
import { getLoginCaptcha, getUserLogin } from '../apis/user'; // api 相关,这里使用了 axios
function Login() {
const navigate = useNavigate();
const [form] = Form.useForm();
const [captchaHint, setCaptchaHint] = useState('获取验证码');
const [disabledCaptchaBtn, setDisabledCaptchaBtn] = useState(false);
const phone = Form.useWatch('phone', form);
// 获取验证码
const getCaptcha = () => {
setDisabledCaptchaBtn(true);
let seconds = 60;
getLoginCaptcha({
flag: 'login-captcha',
phone
}).then((response) => {
// console.log(response, 'response')
})
setCaptchaHint(`${seconds} 秒后尝试`);
let captchaTimer = setInterval(() => {
if(seconds <= 0) {
clearInterval(captchaTimer);
setDisabledCaptchaBtn(false);
setCaptchaHint('获取验证码');
} else {
setCaptchaHint(`${--seconds} 秒后尝试`);
}
}, 1 * 1000)
}
const onFinish = values => {
getUserLogin({
flag: 'admin-login-submit',
captcha: values.captcha
}).then((response) => {
let user_info = response?.data || {};
// 设置到 localStorage 里面
window.localStorage.setItem('admin-user-info', JSON.stringify(user_info));
setUserInfoData(user_info);
navigate('/'); // 导航到首页
})
}
return (
<div className="login">
// 表单
<Form
form={form}
onFinish={onFinish}
footer={
<div style={{ margin: '16px 16px 0', marginTop: '24px' }}>
<Button nativeType='submit' type='primary' block>
提交
</Button>
</div>
}
className="form"
>
<div style={{position: 'relative'}}>
<Form.Item
labelClass="label"
name="phone"
label='联系方式'
rules={[{ required: true, pattern: /^[1][0-9]{10}$/, message: '请输入手机号' }]}
>
<Input type="tel" placeholder='请输入手机号' />
</Form.Item>
<Button size='mini' plain className='captcha-btn' type="primary" disabled={ disabledCaptchaBtn } onClick={() => getCaptcha()}>{ captchaHint }</Button>
</div>
<Form.Item
labelClass="label"
name="captcha"
label='验证码'
rules={[{ required: true, pattern: /^\d{6}$/, message: '请输入6位数字' }]}
>
<Input type="tel" placeholder='请输入验证码' />
</Form.Item>
</Form>
</div>
);
}

然后,我们设置消费者,当 userInfoSubject$ 发生更改后,进行消费~

// arc/components/Header
// 这是一个公共组件 Header
import React, { useState, useEffect } from 'react';
import { getUserInfoData } from '../service/data-manage';
function Header() {
let [userInfo, setUserInfo] = useState({});
useEffect(() => {
// 登陆接口触发
getUserInfoData().subscribe({
next: (data) => {
if(data.usename) { // 有值才设置 setUserInfo,防止在 useEffect 中设置 setUserInfo 无效
setUserInfo(data);
}
}
})
}, [userInfo]);
return (
<header className="header">
{
userInfo.username ? 
<div>名称:{ userInfo.username }</div>:
<div>匿名</div>
}
</header>
);
}
export default Header;

React 结合 Rxjs 使用,管理数据

参考

Thanks for reading.

本文正在参加「金石计划」

原文链接:https://juejin.cn/post/7220075270665306172 作者:Jimmy

(0)
上一篇 2023年4月10日 上午10:12
下一篇 2023年4月10日 上午10:23

相关推荐

发表回复

登录后才能评论