【发布时间】:2019-08-14 08:37:41
【问题描述】:
我有一个数组,每次调用 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;
代码沙盒链接https://codesandbox.io/s/shy-fog-7yplb
如果您要更改例如位置 40 中名为“Algorand”的项目,请单击 true 到 false,这将按预期工作。然而,API 调用会刷新其余数据,“Algorand”可能不再位于第 40 位,但第 40 位的布尔值仍然为 false,并且不会映射到“Algorand”
【问题讨论】:
-
您能为此创建一个工作示例吗?
-
你要我链接一个codeandbox吗?
-
是的,codeandbox 可以工作。
-
给元素一个键(即 n.name)然后将它传递给 handleClick() 以存储值?
-
您正在检查 x === n 哪些是对象。试试 x.id === n.id 虽然我总是发现没有 40 是 Algorand。也许您可以在订单更改时检查更改是否有效。
标签: javascript reactjs local-storage