reactjs - 在反应中更新状态更新的表单组件不会重新渲染
问题描述
我试图在从 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;
解决方案
推荐阅读
- javascript - SlideUp/SlideDown 下拉值
- netty - Netty - 输入流中的 GZIP 问题
- reactjs - React Native 找不到图片
- reactjs - 使用 Typescript 打字的 Mobx 通用观察者
- java - 使用 ant include (apache camel) 获取最新文件
- c# - 根据当前经过身份验证的用户创建 VssCredentials
- java - 为什么以下代码自动装箱到错误的类型并编译?
- qemu - 在linux中构建edk2
- python - django JsonResponce 将带有 slaches 的 json 作为字符串提供
- ffmpeg - 如何将 GOP 大小设置为输入帧速率的倍数?