首页 > 解决方案 > 在反应中更新状态更新的表单组件不会重新渲染

问题描述

我试图在从 API 调用后使用最新字段更新表单,但状态更新正确,但组件不会重新渲染以更新表单。下面是代码

state = {
        newForm: true,
        showHierarchy: true,
        hierarchyData: [],
        formJson: this.props.body,
        gridCols: [],
        loading: true
    };

调用 API 的方法

openStartFormById = (event, data) => {
        event.preventDefault();
        if (data.id !== null) {
            const requestOptions = {
                method: "GET",
                credentials: "include",
            };
            fetch(localStorage.getItem("apiURL") +
                "flowable-task/app/rest/process-instances/" +
                data.id +
                "/start-form",
                requestOptions)
                .then(response => response.json())
                .then(results => {
                    this.setState({ formJson: results, newForm: true });
                    console.log(this.state.formJson);
                })
        }
    }

这是返回组件的方法

getFormRendererIO = () => {
        return (
            <div className="form-renderer-div">
                {this.state.showHierarchy ? (
                    <div className="form-renderer-div-hierarchy">
                        <Hierarchy
                            processName={this.props.processName}
                            treeItems={HierarchyData}
                            openStartFormById={(e, id) => this.openStartFormById(e, id)} />
                    </div>
                ) : (
                        <div></div>
                    )}
                <div
                    className={this.state.showHierarchy ?
                        'form-renderer-div-renderer'
                        : 'form-renderer-div-renderer-without-hierarchy'}>
                    {
                        !this.state.showHierarchy ?
                            (
                                <div>
                                    <span>
                                        <FontAwesomeIcon
                                            icon={faLongArrowAltLeft}
                                            onClick={this.openLandingPage}
                                            className='backIcon'
                                            title='Back'
                                        />
                                        {/* <Button
                                            className='other-button'
                                            onClick={this.openLandingPage}>
                                            Back</Button> */}
                                    </span>
                                </div>
                            ) : (<div></div>)
                    }
                    {console.log(this.state.formJson)}
                    <FormRendererIO
                        processInstanceId={this.props.processInstanceId}
                        body={this.state.formJson}
                        secondForm={this.props.secondForm}
                        completedTask={this.props.completedTask}
                        key={this.props.index}></FormRendererIO>
                </div>
            </div>
        );
    }

下面是渲染功能

render() {
    return (
        <>
            {
                this.state.newForm ? this.getFormRendererIO() : this.getLandingPage()
            }
        </>
    );
}

我想在这里实现的是,一旦 API 的响应在状态变量formJson中更新,FormRendererIO应该重新渲染,因为属性主体侦听this.state.formJson

在下面为 FormRendererIO 添加代码

import React, { Component } from "react";
import ReactDOM from 'react-dom';
import { Form } from 'react-formio';
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
  faTrashAlt
} from "@fortawesome/free-solid-svg-icons";
import {
  createdFormBuilderJsonWithData,
  saveFormIOData
} from "./CommonFunctionFormIO.js";
import { Button } from "reactstrap";
import { Modal } from "react-bootstrap";
import "../../css/modal.css";
import alert from "sweetalert";

const $ = require("jquery");

class FormRendererIO extends Component {
  constructor(props) {
    super(props);
    this.monthNames = [
      "January",
      "February",
      "March",
      "April",
      "May",
      "June",
      "July",
      "August",
      "September",
      "October",
      "November",
      "December",
    ];
    this.body = this.props.body;
    this.showWorkFlow = false;
    this.formId = this.body["id"];
    this.processId = this.body["processId"];
    this.processName = this.body["processName"];
    this.taskId = this.body["taskId"];
    this.processInstanceId = this.props.processInstanceId;
    this.secondForm = this.props.secondForm;
    this.values = {};
    this.formJson = {};
    this.createdFormBuilderJsonWithData = createdFormBuilderJsonWithData.bind(this, this.props.completedTask);
    this.saveFormIOData = saveFormIOData.bind(this);
    this.formJson = createdFormBuilderJsonWithData(this.body, this.props.completedTask);
    this.count = 0;
    this.forceUpdate();
  }

  componentDidMount() {
      localStorage.setItem("formChanged","false");
    window.scrollTo(0, 0);
  }

  th = (date) => {
    if (date > 3 && date < 21) return "th";
    switch (date % 10) {
      case 1:
        return "st";
      case 2:
        return "nd";
      case 3:
        return "rd";
      default:
        return "th";
    }
  };

  submitData = async (e) => {
    try {
      // Formio.createForm(document.getElementById('formio'), 'https://examples.form.io/example');
      //console.log(e);
      // this.formRef.checkValidity();
      //console.log(saveFormIOData(e));
      this.values = {};
      this.values = saveFormIOData(e);
      //console.log(document.getElementById('formio'));
      if (this.secondForm) {
        var json = {};

        json["formId"] = this.formId;
        json["values"] = this.values;


        var requestBody = {
          headers: { "Content-Type": "application/json" },
          method: "POST",
          credentials: "include",
          body: JSON.stringify(json),
        };

        var response = await fetch(
          localStorage.getItem("apiURL") +
          "flowable-task/app/rest/task-forms/" +
          this.taskId,
          requestBody
        );

        if (!response.ok) {
          alert({
            text: "Error occurred",
            icon: "error",
          });
        } else {
          //var body = await response.json();
          // var processInstanceId = body["id"];
          alert({
            text: "Submission Complete",
            icon: "success",
          });
          //ReactDOM.unmountComponentAtNode(FormBuilderSecond);
          localStorage.setItem("formChanged","false");
        }
      } else {
        var todayDate = new Date();

        var dateMonth =
          this.monthNames[todayDate.getMonth()] +
          " " +
          todayDate.getDate() +
          this.th(todayDate.getDate()) +
          " " +
          todayDate.getFullYear();

        var json = {};
        json["processDefinitionId"] = this.processId;

        json["name"] = this.processName + " - " + dateMonth;
        json["formId"] = this.formId;
        json["values"] = this.values;

        var requestBody = {
          headers: { "Content-Type": "application/json" },
          method: "POST",
          credentials: "include",
          body: JSON.stringify(json),
        };

        var response = await fetch(
          localStorage.getItem("apiURL") +
          "flowable-task/app/rest/process-instances/",
          requestBody
        );

        if (!response.ok) {
          alert({
            text: "Error occurred",
            icon: "error",
          });

        } else {
          var body = await response.json();
          var processInstanceId = body["id"];
          alert({
            text: "Submission Complete",
            icon: "success",
          });
          localStorage.setItem("formChanged","false");
        }
      }
    } catch (error) {
      alert({
        text: "Error occurred",
        icon: "error",
      });

    }
    window.scrollTo(0, 0);
  }

  showDiagram = () => {
    if (this.processInstanceId != "" && this.processInstanceId != null) {
      localStorage.setItem("processInstanceId", this.processInstanceId);
      var jsURL = localStorage.getItem("apiURL") + "GRCNextBPMN/workFlowFiles/";
      const angularScript = document.createElement("script");
      angularScript.src = jsURL + "angular.js";
      angularScript.async = false;
      document.body.appendChild(angularScript);

      const jQueryScript = document.createElement("script");
      jQueryScript.src = jsURL + "/jquery.js";
      jQueryScript.async = false;
      document.body.appendChild(jQueryScript);

      const jQueryMinScript = document.createElement("script");
      jQueryMinScript.src = jsURL + "/jquery.qtip.min.js";
      jQueryMinScript.async = false;
      document.body.appendChild(jQueryMinScript);

      const raphaelScript = document.createElement("script");
      raphaelScript.src = jsURL + "/raphael.min.js";
      raphaelScript.async = false;
      document.body.appendChild(raphaelScript);

      const bpmnDrawScript = document.createElement("script");
      bpmnDrawScript.src = jsURL + "/bpmn-draw.js";
      bpmnDrawScript.async = false;
      document.body.appendChild(bpmnDrawScript);

      const bpmnIconsScript = document.createElement("script");
      bpmnIconsScript.src = jsURL + "/bpmn-icons.js";
      bpmnIconsScript.async = false;
      document.body.appendChild(bpmnIconsScript);

      const polyLineScript = document.createElement("script");
      polyLineScript.src = jsURL + "/Polyline.js";
      polyLineScript.async = false;
      document.body.appendChild(polyLineScript);

      const displayModelScript = document.createElement("script");
      displayModelScript.src = jsURL + "/displaymodel.js";
      displayModelScript.async = false;
      document.body.appendChild(displayModelScript);

      this.showWorkFlow = true;
    } else {
      alert({
        text: "No Data for WorkFlow",
        icon: "warning",
      });
    }
    this.forceUpdate();
  };

  handleClose = () => {
    this.showWorkFlow = false;
    this.forceUpdate();
  };
  
  
  formIoChanged = (schema) => {
    console.log(schema);
    console.log(this.count);
    if (this.count > 0)
      localStorage.setItem("formChanged", "true");
    this.count = this.count + 1;
    this.forceUpdate();
  }

  render() {
    return (
      <>
        <Modal show={this.showWorkFlow} onHide={this.handleClose}>
          <Modal.Body>
            <div className="form-group" style={{ width: "inherit" }}>
              <div id="bpmnModel" style={{ width: "inherit" }} />
            </div>
          </Modal.Body>
          <Modal.Footer>
            <div
              className="text-center"
              style={{ inlineSize: "-webkit-fill-available" }}>
              <Button
                className="form-control"
                style={{ width: 80 }}
                onClick={this.handleClose}>
                Close
              </Button>
            </div>
          </Modal.Footer>
        </Modal>

        <Form src={this.formJson} onSubmit={this.submitData} onChange={(schema) => this.formIoChanged(schema)} />
        {this.processInstanceId != "" && this.processInstanceId != null ? (
          <Button
            className="other-button"
            onClick={this.showDiagram.bind(this)}
            id="showDiagram"
            aria-label="Login">
            Show Diagram
          </Button>
        ) : ""
        }
      </>
    );
  }
}

export default FormRendererIO;

标签: reactjs

解决方案


推荐阅读