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

前言

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

业务场景介绍

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

主页面代码

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

// 主页面代码
import React, {
    
     Component } from "react";
import {
    
    
  Table,
  Form,
  Button,
  Input,
  Collapse,
  Pagination,
  Divider,
  message,
  Modal,
} from "antd";
// ...
const {
    
     Column } = Table;
const {
    
     Panel } = Collapse;
const {
    
     confirm } = Modal;
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 {
    
     projectId, selectedCompany, userParentList } = 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>

          {
    
    /* 审批流程 */}
          <div style={
    
    {
    
     display: this.state.selectedCompany ? 'flex' : 'none', alignItems: 'flex-start' }}>
               <div style={
    
    {
    
     marginRight: '20px' }}>
                   <h4 style={
    
    {
    
     margin: 0 }}>【审批流程】:</h4>
               </div>
               <Timeline style={
    
    {
    
     flex: 1 }}>
                   {
    
    userParentList && userParentList.length > 0 && userParentList.map((user, index) => (
                       <Timeline.Item key={
    
    user.key} color="green">
                           <div>
                               {
    
    user.value}
                           </div>
                       </Timeline.Item>
                   ))}
               </Timeline>
           </div>
        </Form>
      </div>
    );
  }
}

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

在这里插入图片描述

数据传递原理

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

总结

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

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

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

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

猜你喜欢

转载自blog.csdn.net/Da_zhenzai/article/details/132476698