在渲染 React 中过滤获取的数组
Filtering fetched array in render React
这里是 React 的新手,所以请多多包涵。我从服务器获取数据列表,并通过 componentDidMount
函数将其放入 State
中。在其中,我将数据推送到名为 solo
的状态数组。在我尝试渲染数组之前,它工作得很好。我需要过滤我的数组以根据一个 属性 (categ
) 匹配另一个数组中的 属性 来映射数据,并在正确的类别中创建按钮。当我 运行 我的代码时,我只呈现一个按钮,以我的 solo
数组中第一个为准,其中显示了我的所有数据。我确定它与 fetch
的异步性质有关,但我不明白是什么。
这是我的代码:
componentDidMount(){
// Get URLS from config
const data = this.props.config.layerUrls
// Init state values
let categ = [...this.state.categ]
let solo = [...this.state.solo]
// Loop through categories
for (let i = 0; i < data.length; i++) {
let donneesCateg = data[i]
let listURLS = donneesCateg["urls"]
categ.push({['categ']: donneesCateg["name"], ['type']: "categ", ['urls']: listURLS })
this.setState({ categ : categ })
// Loop through individual URL data
for (let a = 0; a < listURLS.length; a++) {
fetch(listURLS[a] + "?f=pjson")
.then(res => res.json())
.then(data => {
// Push to state array
solo.push({['categ']: donneesCateg["name"], ["type"]: "solo", ["couche"]: data.name, ["url"]: listURLS[a] })
this.setState({ solo : solo })
})
}
}
}
render() {
{
return (
<p className="shadow-lg m-3 p-1 bg-white rounded">
{this.state.categ.length!=0 ? this.state.categ.map(item => {
return (
<div>
<button id={item.categ} className="categ" value={item.urls} onClick={this.selectChangeMultiple}>{item.categ}</button>
{this.state.solo.length!=0 ? this.state.solo.filter(solo => solo.categ == item.categ).map(data =>
<button id={data.categ} className="btn" value={data.url} onClick={this.selectChangeSingle}>{data.couche}</button>
) : <p id="loadingMsg">Solo data Loading...</p>}
</div>
)
}) : <p id="loadingMsg">Categ data Loading...</p>}
</p>
</div>
);
}
}
注意:我必须通过这个循环系统,因为我用来获取数据的 URL 在 JSON 中,它们按类别存储在其中。
非常感谢。
在您的代码中,对 setState({solo: solo})
的任何后续调用都不会被 React 识别为更新。发生这种情况是因为 solo
始终是相同的“对象”(尽管与 push
发生了变异,但 React 比较算法并没有比较新的和以前的。它只是比较旧的和新的solo
s 类似 ===
.
一个明显的解决方法是调用 this.setState({ solo : [...solo] })
而不是 this.setState({ solo : solo })
,尽管它仍然可能导致过多的额外重新渲染。但这将是一个好的开始。
这里是 React 的新手,所以请多多包涵。我从服务器获取数据列表,并通过 componentDidMount
函数将其放入 State
中。在其中,我将数据推送到名为 solo
的状态数组。在我尝试渲染数组之前,它工作得很好。我需要过滤我的数组以根据一个 属性 (categ
) 匹配另一个数组中的 属性 来映射数据,并在正确的类别中创建按钮。当我 运行 我的代码时,我只呈现一个按钮,以我的 solo
数组中第一个为准,其中显示了我的所有数据。我确定它与 fetch
的异步性质有关,但我不明白是什么。
这是我的代码:
componentDidMount(){
// Get URLS from config
const data = this.props.config.layerUrls
// Init state values
let categ = [...this.state.categ]
let solo = [...this.state.solo]
// Loop through categories
for (let i = 0; i < data.length; i++) {
let donneesCateg = data[i]
let listURLS = donneesCateg["urls"]
categ.push({['categ']: donneesCateg["name"], ['type']: "categ", ['urls']: listURLS })
this.setState({ categ : categ })
// Loop through individual URL data
for (let a = 0; a < listURLS.length; a++) {
fetch(listURLS[a] + "?f=pjson")
.then(res => res.json())
.then(data => {
// Push to state array
solo.push({['categ']: donneesCateg["name"], ["type"]: "solo", ["couche"]: data.name, ["url"]: listURLS[a] })
this.setState({ solo : solo })
})
}
}
}
render() {
{
return (
<p className="shadow-lg m-3 p-1 bg-white rounded">
{this.state.categ.length!=0 ? this.state.categ.map(item => {
return (
<div>
<button id={item.categ} className="categ" value={item.urls} onClick={this.selectChangeMultiple}>{item.categ}</button>
{this.state.solo.length!=0 ? this.state.solo.filter(solo => solo.categ == item.categ).map(data =>
<button id={data.categ} className="btn" value={data.url} onClick={this.selectChangeSingle}>{data.couche}</button>
) : <p id="loadingMsg">Solo data Loading...</p>}
</div>
)
}) : <p id="loadingMsg">Categ data Loading...</p>}
</p>
</div>
);
}
}
注意:我必须通过这个循环系统,因为我用来获取数据的 URL 在 JSON 中,它们按类别存储在其中。 非常感谢。
在您的代码中,对 setState({solo: solo})
的任何后续调用都不会被 React 识别为更新。发生这种情况是因为 solo
始终是相同的“对象”(尽管与 push
发生了变异,但 React 比较算法并没有比较新的和以前的。它只是比较旧的和新的solo
s 类似 ===
.
一个明显的解决方法是调用 this.setState({ solo : [...solo] })
而不是 this.setState({ solo : solo })
,尽管它仍然可能导致过多的额外重新渲染。但这将是一个好的开始。