我有一个数组,每次调用componentDidMount()时都会提取API数据。我有一个默认值为true的对象,该对象推入数组中的每个元素。设置了onClick函数,以便在单击特定元素时,其布尔值将更改为false并将该数组放置在localStorage中。
我需要数据数组在每次重新加载页面时不断刷新,因此我在我的componentDidMount()方法中进行了检查,该方法仅从刚保存在localStorage中的数组接收布尔值。
尽管这可行,但布尔值是根据索引而不是元素本身分配的。这里的问题是,如果位置2的元素“ A”最初设置为false,然后在另一个API调用之后与位置3的元素“ B”交换,则布尔值将不正确,因为现在的“ B”为假,“ A”现在为真。
import React from 'react';
import StarBorder from '@material-ui/icons/StarBorder';
import Star from '@material-ui/icons/Star';
import axios from 'axios';
class Test extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
}
}
componentDidMount() {
axios.get('https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&per_page=100&page=1&sparkline=true')
.then(res => {
const data = res.data;
const fromLocalStorage = localStorage.getItem('test');
if (localStorage.getItem('test')) {
const dataFromLocalStorage = JSON.parse(fromLocalStorage);
this.setState({ data: data.map((x, i) => ({...x, starIcon: dataFromLocalStorage[i].starIcon }))})
} else {
this.setState({ data: data.map(x => ({...x, starIcon: true}))})
}
})
}
handleClick = (n) => {
this.setState(prevState => ({
data: prevState.data.map((x) => (x === n ? {
...x,
starIcon: !x.starIcon
} : x))
})
, () => {
localStorage.setItem('test', JSON.stringify(this.state.data));
});
}
render() {
return (
<div>
<table border="1">
<thead>
<tr>
<td>Rank</td>
<td>Icon</td>
<td>Name</td>
<td>Price</td>
</tr>
</thead>
<tbody>
{this.state.data.map((n, i) => {
return (
<tr>
<td>{n.market_cap_rank}</td>
<td> <span onClick={() => this.handleClick(n)}> {n.starIcon ? <StarBorder/> : <Star /> } </span> </td>
<td>{n.name}</td>
<td>{n.current_price}</td>
</tr>
);
})}
</tbody>
</table>
</div>
);
}
}
export default Test;
Codesandbox链接https://codesandbox.io/s/shy-fog-7yplb
如果要更改位置40上名为“ Algorand”的示例项目,请单击true到false来按预期工作。但是,API调用将刷新其余数据,并且“ Algorand”可能不再位于位置40,但是位置40的布尔值仍然为false,并且未映射到“ Algorand”
答案 0 :(得分:1)
尝试在您的componentDidMount中使用它
class MyProgramLauncher {public static void main(String[] args) {MyProgram.main(args);}}
我要做的是在您映射状态下的刷新数据时,我没有从整个对象中匹配(这将无法正常工作),而是从数组中找到了正确的对象,并从其中使用了startIcon。