对于有经验的程序员,我认为这应该很简单。我花了几个小时,最后是时候从别人那里寻求帮助了。
我正在使用Ant.Design UI模板提供的Tree组件来实现React。我需要从API加载数据以填充树。我要实现的是当用户单击树中的项目以展开它时,从api异步加载数据(子项)。我使用fetch()。then()。then()。catch()编写了一个函数onLoadData来实现此目的。但是,当用户单击以展开树时,会出现标题中所述的错误。为什么会发生此错误?我该如何解决这个问题?
import React from 'react';
import {Tree} from 'antd';
import 'antd/dist/antd.css';
import '../App.css';
const {TreeNode} = Tree;
export class DeptFilter extends React.Component{
state = {
treeData: [{title: 'All Department', key: 0}],
error: null,
};
onLoadData = treeNode => {
console.log(treeNode);
if(treeNode.props.children) return;
let url = '39.108.130.214:8080/rest/depts/subdepts/' + treeNode.props.dataRef.key;
console.log('URL: ' + url);
fetch(url)
.then(response => response.json())
.then(json => {
treeNode.props.dataRef.children = json;
this.setState({
treeData: [...this.state.treeData],
})
})
.catch(error => {
this.setState({
error
})
});
};
renderTreeNodes = data =>
data.map(item => {
console.log('children: ' + item.children);
console.log('title: ' + item.title);
if (item.children) {
return (
<TreeNode title={item.title} key={item.key} dataRef={item}>
{this.renderTreeNodes(item.children)}
</TreeNode>
)
}
return(<TreeNode title={item.title} key={item.key} dataRef={item} />);
});
render() {
return (
<div>
<h2>Department</h2>
<Tree loadData={this.onLoadData}>{this.renderTreeNodes(this.state.treeData)}</Tree>
<div>{this.state.error && <h3>{this.state.error}</h3>}</div>
</div>
);
}
}
浏览器控制台产生了以下错误核心
[Log] TreeNode {props: Object, context: Object, refs: {}, updater: Object, onSelectorClick: function, …} (main.chunk.js, line 565)
[Log] URL: 39.108.130.214:8080/rest/depts/subdepts/0 (main.chunk.js, line 568)
[Log] TreeNode {props: Object, context: Object, refs: {}, updater: Object, onSelectorClick: function, …} (main.chunk.js, line 565)
[Log] URL: 39.108.130.214:8080/rest/depts/subdepts/0 (main.chunk.js, line 568)
[Error] TypeError: undefined is not an object (evaluating 'promise.then')
(anonymous function) (0.chunk.js:138818)
getStateFromUpdate (0.chunk.js:161420)
processUpdateQueue (0.chunk.js:161484)
updateClassInstance (0.chunk.js:156583)
updateClassComponent (0.chunk.js:159758)
performUnitOfWork (0.chunk.js:164766)
workLoop (0.chunk.js:164807)
callCallback (0.chunk.js:144634)
dispatchEvent
invokeGuardedCallbackDev (0.chunk.js:144683)
invokeGuardedCallback (0.chunk.js:144737)
replayUnitOfWork (0.chunk.js:163990)
renderRoot (0.chunk.js:164920)
performWorkOnRoot (0.chunk.js:165844)
performWork (0.chunk.js:165754)
performSyncWork (0.chunk.js:165728)
interactiveUpdates$1 (0.chunk.js:166013)
dispatchInteractiveEvent (0.chunk.js:149572)
dispatchInteractiveEvent
[Error] The above error occurred in the <Tree> component:
in Tree (created by Context.Consumer)
in Tree (at Dept.jsx:58)
in div (at Dept.jsx:56)
in DeptFilter (at Staff.jsx:7)
in div (at Staff.jsx:6)
in StaffMain (at App.js:24)
in Route (at App.js:22)
in PrivateRoute (at App.js:73)
in Switch (at App.js:71)
in div (at App.js:70)
in main (created by Basic)
in Basic (created by Context.Consumer)
in Adapter (at App.js:68)
in section (created by BasicLayout)
in BasicLayout (created by Context.Consumer)
in Adapter (at App.js:63)
in Router (created by BrowserRouter)
in BrowserRouter (at App.js:62)
in App (at src/index.js:7)
Consider adding an error boundary to your tree to customize error handling behavior.
logCapturedError (0.chunk.js:162361)
logError (0.chunk.js:162397)
callback (0.chunk.js:163420)
callCallback (0.chunk.js:161588)
commitUpdateEffects (0.chunk.js:161628)
commitUpdateQueue (0.chunk.js:161618)
commitLifeCycles (0.chunk.js:162653)
commitAllLifeCycles (0.chunk.js:164155)
callCallback (0.chunk.js:144634)
dispatchEvent
invokeGuardedCallbackDev (0.chunk.js:144683)
invokeGuardedCallback (0.chunk.js:144737)
commitRoot (0.chunk.js:164379)
(anonymous function) (0.chunk.js:165927)
unstable_runWithPriority (0.chunk.js:178509)
completeRoot (0.chunk.js:165926)
performWorkOnRoot (0.chunk.js:165849)
performWork (0.chunk.js:165754)
performSyncWork (0.chunk.js:165728)
interactiveUpdates$1 (0.chunk.js:166013)
dispatchInteractiveEvent (0.chunk.js:149572)
dispatchInteractiveEvent
[Error] TypeError: undefined is not an object (evaluating 'promise.then')
finishRendering (0.chunk.js:165814)
performWork (0.chunk.js:165773)
performSyncWork (0.chunk.js:165728)
interactiveUpdates$1 (0.chunk.js:166013)
dispatchInteractiveEvent (0.chunk.js:149572)
dispatchInteractiveEvent
[Error] Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
in DeptFilter (at Staff.jsx:7)
in div (at Staff.jsx:6)
in StaffMain (at App.js:24)
in Route (at App.js:22)
in PrivateRoute (at App.js:76)
in Switch (at App.js:71)
in div (at App.js:70)
in main (created by Basic)
in Basic (created by Context.Consumer)
in Adapter (at App.js:68)
in section (created by BasicLayout)
in BasicLayout (created by Context.Consumer)
in Adapter (at App.js:63)
in Router (created by BrowserRouter)
in BrowserRouter (at App.js:62)
in App (at src/index.js:7)
warningWithoutStack (0.chunk.js:145007)
warnAboutUpdateOnUnmounted (0.chunk.js:163882)
scheduleWork (0.chunk.js:165369)
enqueueSetState (0.chunk.js:156082)
setState (0.chunk.js:174824)
(anonymous function) (main.chunk.js:575)
promiseReactionJob
我已将完整代码上传到CodeSandBox(https://codesandbox.io/s/frosty-beaver-ms7ke)。错误发生在Dept.jsx
什么会导致“未定义的不是对象”?