我有一个父组件,里面有 Hierarchy 组件。父组件根据状态中变量 newform
的值有条件地渲染
getFormRendererIO = () => {
return (
<div className="form-renderer-div">
{this.state.showHierarchy ? (
<div className="form-renderer-div-hierarchy">
<Hierarchy
processName={this.props.processName}
// treeItems={HierarchyData}
body={this.props.body}
treeItems={this.state.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>)
}
<div>
<FormRendererIO
processInstanceId={this.props.processInstanceId}
body={this.state.formJson}
secondForm={this.props.secondForm}
completedTask={this.state.completedTask}
key={this.props.index}></FormRendererIO>
{
this.state.showHierarchy ? (
<span>
<Button
className='other-button'
onClick={this.openNewForm}>
New</Button>
{/* <FontAwesomeIcon
icon={faPlus}
onClick={this.openNewForm}
className='plusIcon'
title='New' /> */}
</span>
) : (<div></div>)
}
</div>
</div>
</div>
);
}
render() {
return (
<>
{
this.state.newForm ? this.getFormRendererIO() : this.getLandingPage()
}
</>
);
}
下面是 Hierarchy 组件
class Hierarchy extends Component {
state = {
hierarchyData: []
};
constructor(props) {
super(props);
}
getTreeItemsFromData = (treeItems, index) => {
// var hierarchyDataStr = localStorage.getItem("hierarchyData");
// console.log(hierarchyDataStr ? JSON.parse(hierarchyDataStr) : 'NULL');
console.log(treeItems);
if (treeItems.length > 0) {
return treeItems.map((treeItemData) => {
let children = undefined;
if (treeItemData.children && treeItemData.children.length > 0) {
children = this.getTreeItemsFromData(treeItemData.children);
}
return (
<SidebarLink>
<StyledTreeItem
key={treeItemData.parent}
nodeId={treeItemData.parent}
label={treeItemData.parent === 'root' ? '' : treeItemData.parent}
children={children}
// onClick={() => handleClick(treeItemData.id)}
onClick={(e) => this.props.openStartFormById(e, treeItemData)}
/>
</SidebarLink>
);
});
}
}
render() {
return (
<TreeView
// className={this.classes.root}
defaultExpanded={["1"]}
defaultCollapseIcon={<MinusSquare />}
defaultExpandIcon={<PlusSquare />}
defaultEndIcon={<CloseSquare />}
>
{this.getTreeItemsFromData(this.props.treeItems)}
</TreeView>
)
};
}
export default Hierarchy;
我在 Parent componentDidMount()
中有一个 API,它更新 hierarchyData
的状态,最终在 Hierarchy 中作为 props 传递。
下面是调用API的方法
async getHierarchyFromAPI() {
var formIOString = this.props.body.formIoString;
var parentId = 'parent';
var childId = 'child';
var decisionId = 'decision';
console.log(formIOString);
if (formIOString) {
var formIOJSON = JSON.parse(formIOString);
var formComponents = formIOJSON.components;
console.log(formComponents);
for (var i = 0; i < formComponents.length; i++) {
console.log(formComponents[i]["description"]);
if (formComponents[i]["key"] === 'parent') {
parentId = this.getElementId(formComponents[i]);
parentId = formComponents[i]["key"];
}
if (formComponents[i]["name"] === 'child') {
childId = this.getElementId(formComponents[i]);
childId = formComponents[i]["name"];
}
if (formComponents[i]["key"] === 'decision') {
decisionId = formComponents[i]["key"];
}
}
}
const requestOptions = {
method: "GET",
credentials: "include",
};
let data = await fetch(localStorage.getItem("apiURL") +
'/GRCNextBPMN/getHeirarchyData?processKey=' + this.props.processName.replace(/\s+/g, "")
+ '&parent=' + parentId
+ '&child=name' //+ childId
+ '&decisionId=' + decisionId
+ '&decisionValue=Approved',
requestOptions)
.then(response => response.json())
this.setState({ hierarchyData: data });
}
我面临的问题是 API 调用是异步的,当 hierarchyData
更新时,Hierarchy
组件已经呈现并且显示为空白。
我希望在 API 调用完成并且应该呈现组件后更新 Hierarchy
组件中的hierarchyData。请提出解决问题的可能解决方案
添加了 componentDidMount
方法
componentDidMount() {
if (this.landingPages.includes(this.props.processName)) {
const requestOptions = {
method: "GET",
credentials: "include",
};
fetch(localStorage.getItem("apiURL") +
'/GRCNextBPMN/getGridCols/' +
this.props.processName.replace(/\s+/g, ""),
requestOptions)
.then(response => response.json())
.then(results => {
this.setState({
gridCols: results,
newForm: false,
showHierarchy: false
});
})
} else {
this.getHierarchyFromAPI();
}
}