【发布时间】:2020-07-30 20:02:53
【问题描述】:
我目前正在尝试让一个项目工作以测试一些东西,但我正处于尝试正确更新状态的地步。
我有一个通过axios.get("/docker/containers") 访问的端点,它将为当前在我的系统上运行的容器的所有 ID 返回一个数组,如下所示:
componentDidMount() {
this.interval = setInterval(() => this.updateContainers(), 3000);
};
componentWillUnmount() {
clearInterval(this.interval);
}
此时我的状态如下:
state = {
containers: [{id: 'id1'}, {id: 'id2'}]
}
然后用户界面只显示一个 ID 列表。
然后我可以在我的用户界面上单击一个 ID,它会设置一个观察者:
state = {
containers: [{id: 'id1', watcher: true}, {id: 'id2'}]
}
观察者的目的是为了在下一个更新周期中检索有关特定容器的更详细信息。
state = {
containers: [{id: 'id1', watcher: true, name: 'container1'}, {id: 'id2'}]
}
单击用户界面中已设置watcher 的容器后,watcher 将被删除,然后不再检索更详细的信息
state = {
containers: [{id: 'id1', watcher: false}, {id: 'id2'}]
}
我遇到的困难是如何获取更详细的信息。我的updateContainers 方法有3个步骤:
-
从 API 读取响应并将状态分解为单独的变量,将状态 var 与响应 var 进行比较,并删除所有已关闭的容器(此处未完成
setState)。 -
将响应中的任何新容器添加到此后出现的状态(同样没有
setState)。
...到目前为止一切顺利...
- 循环遍历步骤 1 和 2 中过滤的容器数组,找到任何设置了
watcher的容器。在设置位置执行 API 调用以检索更详细的信息。最后设置状态。
在第 3 步中,我在过滤后的数组上使用forEach,然后执行axios.get("/docker/containers/id1"),其中设置了watcher,否则只需保留我已经拥有的容器详细信息,但这就是我卡住的地方, Typescript 也给了我错误:
TS2322: Type 'void' is not assignable to type 'IndividualContainer[]'.
目前我有:
updateContainers() {
axios.get('/docker/containers')
.then(response => {
const apiRequestedContainers: string[] = response.data.containers;
// array of only IDs
const stateContainers: IndividualContainer[] = [
...this.state.containers
];
// remove dead containers from state by copying still live containers
let filteredContainers: IndividualContainer[] = [
...this.filterOutContainers(stateContainers, apiRequestedContainers)
];
// add new containers
filteredContainers = this.addContainerToArray(
filteredContainers, apiRequestedContainers
);
return this.updateContainer(filteredContainers);
})
.then(finalArray => {
const newState: CState = {'containers': finalArray};
this.setState(newState);
});
};
updateContainer(containers: IndividualContainer[]) {
const returnArray: IndividualContainer[] = [];
containers.forEach(container => {
if (container.watcher) {
axios.get('/docker/containers/' + container.id)
.then(response => {
// read currently available array of containers into an array
const resp = response.data;
resp['id'] = container.id;
resp['watcher'] = true;
returnArray.push(resp);
});
} else {
returnArray.push(container);
}
return returnArray;
});
};
任何指向我的逻辑失败的地方都将不胜感激!
编辑:
渲染方法:
render() {
const containers: any = [];
const curStateOfContainers: IndividualContainer[] = [...this.state.containers];
if (curStateOfContainers.length > 0) {
curStateOfContainers.map(container => {
const container_id = container.id.slice(0, 12);
containers.push(
<Container
key = {container_id}
container_id = {container.id}
name = {container.name}
clickHandler = {() => this.setWatcher(container.id)}
/>
);
});
}
return containers;
}
【问题讨论】:
-
请解释方法
addContainerToArray -
在该方法中,我将容器从我的初始响应对象添加到状态。例如,在新容器上线的情况下。
-
请解释一下这个方法。它应该返回一个 IndividualContainer 数组
-
哪一行给出了 TS 错误?
-
所以该方法取了2个数组,第一个数组是已经处于app状态的容器,第二个是最近一次get请求接收到的容器,get请求中任何不处于该状态的容器然后添加,两个数组中的任何容器都会从状态中保留,这是由于需要保留观察者参数。
标签: reactjs typescript api axios