likes
comments
collection
share

React 结合 Rxjs 使用,管理数据

作者站长头像
站长
· 阅读数 42

前言

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

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

Rxjs 是什么

安装 Rxjs

"react" 版本为 "^18.2.0"

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

npm install rxjs

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

结合 React,使用 Rxjs

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

我们新建一个数据管理的 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';

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;

React 结合 Rxjs 使用,管理数据

参考

Thanks for reading.

转载自:https://juejin.cn/post/7220075270665306172
评论
请登录