前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >React 结合 Rxjs 使用,管理数据

React 结合 Rxjs 使用,管理数据

作者头像
Jimmy_is_jimmy
发布2023-04-22 19:48:13
1.6K0
发布2023-04-22 19:48:13
举报
文章被收录于专栏:call_me_Rcall_me_R

前言

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

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

Rxjs 是什么

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

安装 Rxjs

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

"react" 版本为 "^18.2.0"

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

代码语言:javascript
复制
npm install rxjs

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

结合 React,使用 Rxjs

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

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

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

代码语言: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$ 的值:

代码语言:javascript
复制
// 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$ 发生更改后,进行消费~

代码语言:javascript
复制
// arc/components/Header
// 这是一个公共组件 Header
import React, { useState, useEffect } from 'react';
import { getUserInfoData } from '../service/data-manage';

let subscriptionUserInfo = null;
function Header() {
  let [userInfo, setUserInfo] = useState({});

  useEffect(() => {
    // 登陆接口触发
    subscriptionUserInfo = getUserInfoData().subscribe({
      next: (data) => {
        if(data.usename) { // 有值才设置 setUserInfo,防止在 useEffect 中设置 setUserInfo 无效
          setUserInfo(data);
        }
      }
    })
    
    return () => {
      // 取消订阅
      subscriptionUserInfo.unsubscribe();
    }
  }, []);

  return (
    <header className="header">
      {
        userInfo.username ? 
        <div>名称:{ userInfo.username }</div>:
        <div>匿名</div>
      }
      
    </header>
  );
}

export default Header;

参考

Thanks for reading.

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-04-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • Rxjs 是什么
  • 安装 Rxjs
  • 结合 React,使用 Rxjs
  • 参考
相关产品与服务
验证码
腾讯云新一代行为验证码(Captcha),基于十道安全栅栏, 为网页、App、小程序开发者打造立体、全面的人机验证。最大程度保护注册登录、活动秒杀、点赞发帖、数据保护等各大场景下业务安全的同时,提供更精细化的用户体验。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档