React组件间数据传递(弹框和高阶组件(HOC)特性实现)

news2025/1/12 0:59:12

前言

在现代前端开发中,React 已经成为了最受欢迎的 JavaScript 库之一。而在复杂的应用中,不同组件之间的数据传递问题显得尤为关键。在本文中,我们将探讨一种高效的方法,即如何利用弹框和高阶组件特性来实现 React 组件间的数据传递。我们将通过一个具体的业务场景来深入讲解

业务场景介绍

假设我们正在开发一个项目管理系统,其中一个关键功能是发起项目立项审批。在主页面上,用户可以看到一张项目列表,每个项目都带有一个“发起审批”按钮。点击该按钮后,一个弹框将显示,允许用户选择公司部门并查看相关的审批流程。在这个过程中,我们需要实现从主页面向弹框组件传递数据,并根据用户的选择加载相关的审批流程。

主页面代码

首先,我们有一个名为 ProjectManagement 的主页面组件。在这个组件中,我们为每个项目都添加了一个“发起审批”按钮,点击该按钮会触发 handleGoApprove 方法,将项目数据传递给弹框组件,弹框组件点击确认按钮触发handleApproveOk方法调用后端接口。

// 主页面代码
class ProjectManagement extends Component {
  // ... 其他状态和方法 ...

  // 处理发起审批按钮点击
  handleGoApprove = (row) => {
    // 更新状态,传递数据到弹框组件
    this.setState({
      currentRowData: Object.assign({}, row),
      approveModalFormVisible: true,
      // ...
    });
  };
  // 处理子组件确认提交按钮
  handleApproveOk = (_) => {
    // 获取子组件的props
    const { form } = this.approveItemFormRef.props;
    form.validateFields((err, fieldsValue) => {
      if (err) {
        return;
      }
      // 获取API所需的参数
      const projectId = form.getFieldValue("projectId");
      const selectedCompany = form.getFieldValue("departCompany");
      const values = {
        ...fieldsValue,
        projectId: projectId,
        selectedCompany: selectedCompany,
      };
      // 调用API
      this.setState({ approveModalFormLoading: true });
      toApprove(values)
        .then((response) => {
          form.resetFields();
          this.setState({ approveModalFormVisible: false, approveModalFormLoading: false });
          message.success("发起成功!");
          this.fetchData();
        })
        .catch((e) => {
          message.success("发起失败,请重试!");
          this.setState({ approveModalFormLoading: false });
        });
    });
  };
  // ... 其他渲染逻辑 ...

  render() {
    return (
      <div className="app-container">
        {/* 表格代码 */}
        <Table>
          {/* 列定义 */}
          <Column
            render={(text, row) => (
              <Button
                onClick={() => this.handleGoApprove(row)}
              >
                发起立项审批
              </Button>
            )}
          />
        </Table>

        {/* 弹框 */}
        <Modal
          title="发起立项审批"
          visible={this.state.approveModalFormVisible}
          onCancel={this.handleCancel}
          onOk={this.handleApproveOk}
          // ...
        >
          {/* 弹框内容 */}
          <ApproveModal
            currentRowData={this.state.currentRowData}
            wrappedComponentRef={(formRef) => (this.approveItemFormRef = formRef)}
            // ...
          />
        </Modal>
      </div>
    );
  }
}

弹框组件代码

接下来,让我们看看弹框组件 ApproveModal 的代码。在 componentWillMount 生命周期中,我们根据传入的 currentRowData 获取项目数据,并在状态中初始化相关信息。然后,通过 getDepartLevelByUser 方法获取部门层级信息,并将数据存储在状态中。

class ApproveModal extends Component {
  state = {
        userParentList: [],
        departCompanyList: [],
        selectedCompany: '', // 用于存储选中的公司
        projectId: '',
  }
  componentWillMount() {
    const { currentRowData } = this.props;
    const projectId = currentRowData.id;
    const departmentManager = currentRowData.departmentManager;

    // 根据当前行数据初始化状态
    this.setState({
      projectId: projectId,
    });

    // 获取部门层级信息并初始化状态
    this.getDepartLevelByUser(departmentManager);
  }

  getDepartLevelByUser = (value) => {
    // 使用API获取部门层级数据
    getDepartLevelByUser(value).then((response) => {
      const { data } = response.data;
      this.setState(
        {
          departCompanyList: data,
        },
        () => {
          // 在状态更新后,检查 departCompanyList 是否有记录
          if (this.state.departCompanyList.length > 0) {
            // 默认填充第一条记录的值
            const selectedCompany = this.state.departCompanyList[0].company;
            this.setState(
              {
                selectedCompany: selectedCompany,
              },
              () => {
                // 在设置 selectedCompany 后触发 onChange 事件
                this.handleDepartCompanySelect(selectedCompany);
              }
            );
          }
        }
      );
    });
  }

  // ... 其他逻辑 ...

  render() {
    // 使用 getFieldDecorator 处理表单
    const { getFieldDecorator } = this.props.form;
    const { selectedCompany, departCompanyList } = this.state;

    return (
      <div>
        <Form>
          <Form.Item>
            {getFieldDecorator("departCompany", {
              initialValue: selectedCompany,
              // ...
            })(
              <Select onChange={this.handleDepartCompanySelect} value={selectedCompany}>
                {/* 渲染部门选项 */}
                {departCompanyList.map((item) => (
                  <Select.Option key={item.company} value={item.company}>
                    {item.company}
                  </Select.Option>
                ))}
              </Select>
            )}
          </Form.Item>

          {/* 审批流程 */}
          {selectedCompany && (
            <div>
              <h4>【审批流程】:</h4>
              <ol>
                {/* 渲染审批人员 */}
                {departCompanyList
                  .find((item) => item.company === selectedCompany)
                  .userDtoList?.map((user) => (
                    <li key={user.userId}>{user.username}</li>
                  ))}
              </ol>
            </div>
          )}
        </Form>
      </div>
    );
  }
}

// 利用高阶组件(HOC)封装表单
const WrappedApproveModal = Form.create()(ApproveModal);
export default WrappedApproveModal;

在这里插入图片描述

数据传递原理

在本例中,数据传递是通过主页面状态传递给弹框组件的 currentRowData 属性实现的。弹框组件可以根据传入的数据进行初始化,并根据用户选择加载相应的审批流程。另外,弹框组件还利用高阶组件 Form.create() 来处理表单,从而更方便地管理表单域的值和状态。

总结

通过这个实际的业务场景,我们深入探讨了如何利用弹框和高阶组件特性来实现 React 组件间的数据传递。我们从主页面传递数据到弹框组件,再到表单域,逐步分析了数据传递和状态管理的过程。这种模式可以帮助你更好地组织代码、实现数据流动,并提高项目的可维护性和扩展性。弹框组件内部的 render 方法使用了 getFieldDecorator 处理表单,这让我们可以轻松地管理表单域的值和状态。

通过以上代码和解释,我们了解了一个典型的组件间数据传递方式,以及如何在 React 中利用弹框和高阶组件特性来实现这种方式。这个方法可以应用于许多场景,帮助我们更好地组织代码、处理数据流动,从而构建更出色的应用程序。

如果你在实际项目中遇到了类似的问题,不妨尝试这个方法来处理组件间的数据传递。希望这篇文章对你有所帮助,如果你有任何疑问或想法,请随时在下方留言。感谢阅读!

结束语:只有责任才能让我们的幸福变得厚重

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/923062.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue3 基础知识 ( webpack 基础知识)05

你好 文章目录 一、组件二、如何支持SFC三、webpack 打包工具四、webpack 依赖图五、webpack 代码分包 一、组件 使用组件中我们可以获得非常多的特性&#xff1a; 代码的高亮&#xff1b;ES6、CommonJS的模块化能力&#xff1b;组件作用域的CSS&#xff1b;可以使用预处理器来…

芯片行业震荡期,数字后端还可以入吗?

自去年开始&#xff0c;芯片行业仿佛进入了动荡期&#xff0c;经历了去年秋招和今年春招的小伙伴都知道&#xff0c;如今找工作有多难。 半导体行业人才缩减、各大厂裁员&#xff0c;在加上高校毕业生人数破千万&#xff0c;对于即将踏入IC这个行业的应届生来说&#xff0c;今…

存储过程的使用

一、实验目的 熟练掌握使用 SQL SERVER 2000 创建和执行存储过程的方法。 熟练掌握存储过程的删除操作。 二、实验准备 1&#xff0e;熟悉 SQL SERVER 2000 设计环境&#xff1b; 2&#xff0e;熟悉存过过程的创建方法、步骤 三、实验内容 1、利用企业管理器或查询分析器…

在线OJ平台项目

一、项目源码 Online_Judge yblhlk/Linux课程 - 码云 - 开源中国 (gitee.com) 二、所用技术与开发环境 1.所用技术: MVC架构模式 (模型&#xff0d;视图&#xff0d;控制器) 负载均衡系统设计 多进程、多线程编程 C面向对象编程 & C 11 & STL 标准库 C Boost 准标…

建议收藏|软考机构推荐看这一篇就够了

需要最近因为软考改革成机考&#xff0c;大家都在问还有没有必要找机构学&#xff1f;本来已经进入自学阶段的考生&#xff0c;也纷纷开始慌张机考改革会不会影响考试难度&#xff1f;今天胖圆给大家总结一下软考要不要报机构&#xff1f;市面上的软考培训机构如何选择&#xf…

高手速成|数据库脚本生成工具

高手速成|数据库脚本生成工具 文章目录 高手速成|数据库脚本生成工具前言1、软件的安装及使用2、建立新工程3、创建Conceptual Data Model&#xff08;概念数据模型&#xff09;4、将E-R图转化为其他数据库模型5、导出DBMS代码&#xff08;Sql执行脚本&#xff09;6、执行sql脚…

【boost网络库从青铜到王者】第六篇:asio网络编程中的socket异步读(接收)写(发送)

文章目录 1、简介2、异步写 void AsyncWriteSomeToSocketErr(const std::string& buffer)3、异步写void AsyncWriteSomeToSocket(const std::string& buffer)4、异步写void AsyncSendToSocket(const std::string& buffer)5、异步读void AsyncReadSomeToSocket(cons…

Java 8 Stream 之 collect() 的奇技淫巧

来源&#xff1a;blog.csdn.net/qq_35387940/ article/details/127008965 前言 正文 第一个小玩法 第二个小玩法 前言 本身我是一个比较偏向少使用Stream的人&#xff0c;因为调试比较不方便。 但是, 不得不说&#xff0c;stream确实会给我们编码带来便捷。 所以还是忍…

python开发环境搭建

1、安装python 下载地址&#xff1a;https://www.python.org/downloads/windows/ 双击安装。 安装完验证&#xff1a; 2、安装IDE 下载地圵&#xff1a;https://www.jetbrains.com/zh-cn/pycharm/download/?sectionwindows 免费版本 3、安装依赖包 在项目的根目录下…

【RuoYi移动端】HBuild工具插件安装和系统配置manifest.json

一、点【工具】-【插件安装】安装如下工具 二、点【manifest.json】

搭建Tomcat HTTP服务:在Windows上实现外网远程访问的详细配置与设置教程

文章目录 前言1.本地Tomcat网页搭建1.1 Tomcat安装1.2 配置环境变量1.3 环境配置1.4 Tomcat运行测试1.5 Cpolar安装和注册 2.本地网页发布2.1.Cpolar云端设置2.2 Cpolar本地设置 3.公网访问测试4.结语 前言 Tomcat作为一个轻量级的服务器&#xff0c;不仅名字很有趣&#xff0…

数据库概况

数据的基本概念&#xff1a; ①数据 描述事物的符号记录&#xff0c;包括数字&#xff0c;文字&#xff0c;图形&#xff0c;图形&#xff0c;声音&#xff0c;档案记录等以“记录”形式按统一的格式进行存储。 ②表 将不同的记录组织在一起 用来存储具体数据 ③数据库 表的…

I/O多路复用 select 、poll

前言 套接字通信并发如果我们服务器端想实现并发&#xff0c;有两种处理方式&#xff0c;第一种是通过多进程的方式来处理并发&#xff0c;第二种是通过多线程的方式来处理服务器端的并发。 【问题】如果服务器端的程序只有一个线程&#xff0c;或者说只有一个进程&#xff0…

腾讯云新老用户优惠券免费领取方法分享

腾讯云优惠券是腾讯云的一种优惠方式&#xff0c;领券之后购买腾讯云相关产品可以享受优惠&#xff0c;下面给大家分享腾讯云新老用户优惠券免费领取方法&#xff0c;助力大家轻松上云&#xff01; 一、腾讯云优惠券领取方法 腾讯云新用户优惠券&#xff1a;点此领取 腾讯云老…

ERP系统解析:全面了解企业资源规划系统

在当今快节奏的商业环境中&#xff0c;有效的企业资源计划&#xff08;Enterprise Resource Planning&#xff0c;简称ERP&#xff09;系统对于组织的成功运营至关重要。ERP系统是一种集成管理软件&#xff0c;通过整合各个部门的信息和流程&#xff0c;实现资源的高效利用和运…

11.redis持久化

1.redis持久化 Redis的所有数据都是保存在内存中&#xff0c;因此redis重启后数据就丢失了&#xff0c;所以需要不定期的通过异步方式保存到磁盘上(这称为“半持久化模式”)&#xff1b;或者把每一次数据变化都写入到一个append only file(aof)里面(这称为“全持久化模式”)。 …

Exploring Lottery Prompts for Pre-trained Language Models

Exploring Lottery Prompts for Pre-trained Language Models 文章链接 清深的工作&#xff0c;比较有意思的一篇。作者先给出假设&#xff0c;对于分类问题&#xff0c;在有限的语料空间内总能找到一个prompt让这个问题分类正确&#xff0c;作者称之为lottery prompt。为此&…

Rust常用加密算法

哈希运算(以Sha256为例) main.rs: use crypto::digest::Digest;use crypto::sha2::Sha256;fn main() { let input "dashen"; let mut sha Sha256::new(); sha.input_str(input); println!("{}", sha.result_str());} Cargo.toml: [package]n…

Python中实例方法、类方法、静态方法的区别与作用

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 Python中至少有三种比较常见的方法类型&#xff0c;即实例方法&#xff0c;类方法、静态方法。 它们是如何定义的呢&#xff1f;如何调用的呢&#xff1f;它们又有何区别和作用呢&#xff1f;且看下文。 首先&#xf…

pdf.js构建时,报Cannot read property ‘createChildCompiler‘ of undefined #177的解决方法

在本地和CI工具进行构建时&#xff0c;报如下错误。 Cannot read property createChildCompiler of undefined #177解决方法&#xff1a; 找到vue.config.js&#xff0c;在 module.exports {parallel: false, //新增的一行chainWebpack(config) {....config.module.rule(&…