localStorage 在刷新时使用初始状态值进行更新
localStorage getting updated with initial state value on refresh
我正在尝试使用 localStorage 在刷新时保持组件的状态。
该组件在页面初始呈现时工作正常,但该组件失败并显示消息:TypeError: items.map is not a function
TestLocalStorage
src/TestLocalStorage.jsx:54
代码如下:
import React, { useEffect, useState } from 'react';
function TestLocalStorage() {
const [items, setItems] = useState([]);
useEffect(() => {
const storedData = localStorage.getItem("items");
if(!storedData) {
Axios.get('/url').then(response => {
const serviceResponse = response.data.hits.map(obj=> ({ ...obj, voteCount: 0
}));
localStorage.setItem("items", JSON.stringify(serviceResponse));
setItems(serviceResponse);
});
} else {
setItems(storedData);
}
}, []);
useEffect(() => {
localStorage.setItem("items", JSON.stringify(items));
})
function increment(id) {
const elementsIndex = items.findIndex(element => element.objectID === id )
items[elementsIndex].voteCount++;
setItems([...items]);
}
return (
<table cellPadding="0" cellSpacing="0" width="100%" background-color="#f6f6ef">
<tr>
<td>
<table border="0" cellPadding="0" cellSpacing="0" width="100%">
<tr bgcolor="#ff6600" style={{ color:"white", fontWeight: "bold" }}>
<td> Comments </td>
<td> Vote Count</td>
<td> vote</td>
</tr>
{
items.map((item) => {
return (
<tr className="table-rows" key={item.objectID}>
<td>{ item.comments }</td>
<td>{ item.voteCount }</td>
<td>
<div
style={{
width: 0,
height: 0,
borderTop: 0,
borderLeft: "5px solid transparent",
borderRight: "5px solid transparent",
borderBottom: "10px solid grey"
}}
onClick={() => increment(item.objectID)}
/>
</td>
<td>{ item.title }</td>
</tr>)
})
}
</table>
</td>
</tr>
</table>
);
}
export default TestLocalStorage;
但我注意到在第二次渲染时,localStorage 设置了初始值 [] 而不是新更新的值。不知道我要去哪里错了。
请帮助
storedData
将是字符串,您需要 JSON.parse(storedData)
才能使用它并对其执行 map
使用 JSON.parse()
对您从本地存储中提取的字符串进行解析
function TestLocalStorage() {
const [items, setItems] = useState([]);
useEffect(() => {
const storedData = localStorage.getItem("items");
if(!storedData) {
Axios.get('/url').then(response => {
const serviceResponse = response.data.hits.map(obj=> ({ ...obj, voteCount: 0
}));
localStorage.setItem("items", JSON.stringify(serviceResponse));
setItems(serviceResponse);
});
} else {
setItems(storedData);
}
}, []);
...............
...............
...............
}
像下面那样修改你的函数。此外,在对数组进行映射操作之前检查项目值以防止未捕获的异常
function TestLocalStorage() {
const [items, setItems] = useState([]);
useEffect(() => {
const storedData = JSON.parse(localStorage.getItem("items"));
if(!storedData) {
Axios.get('/url').then(response => {
const serviceResponse = response.data.hits.map(obj=> ({ ...obj, voteCount: 0
}));
localStorage.setItem("items", JSON.stringify(serviceResponse));
setItems(serviceResponse);
});
} else {
setItems(storedData);
}
}, []);
...............
...............
...............
return (
.....
.....
items && items.map((item) => {
.....
.....
)
}
我正在尝试使用 localStorage 在刷新时保持组件的状态。 该组件在页面初始呈现时工作正常,但该组件失败并显示消息:TypeError: items.map is not a function
TestLocalStorage
src/TestLocalStorage.jsx:54
代码如下:
import React, { useEffect, useState } from 'react';
function TestLocalStorage() {
const [items, setItems] = useState([]);
useEffect(() => {
const storedData = localStorage.getItem("items");
if(!storedData) {
Axios.get('/url').then(response => {
const serviceResponse = response.data.hits.map(obj=> ({ ...obj, voteCount: 0
}));
localStorage.setItem("items", JSON.stringify(serviceResponse));
setItems(serviceResponse);
});
} else {
setItems(storedData);
}
}, []);
useEffect(() => {
localStorage.setItem("items", JSON.stringify(items));
})
function increment(id) {
const elementsIndex = items.findIndex(element => element.objectID === id )
items[elementsIndex].voteCount++;
setItems([...items]);
}
return (
<table cellPadding="0" cellSpacing="0" width="100%" background-color="#f6f6ef">
<tr>
<td>
<table border="0" cellPadding="0" cellSpacing="0" width="100%">
<tr bgcolor="#ff6600" style={{ color:"white", fontWeight: "bold" }}>
<td> Comments </td>
<td> Vote Count</td>
<td> vote</td>
</tr>
{
items.map((item) => {
return (
<tr className="table-rows" key={item.objectID}>
<td>{ item.comments }</td>
<td>{ item.voteCount }</td>
<td>
<div
style={{
width: 0,
height: 0,
borderTop: 0,
borderLeft: "5px solid transparent",
borderRight: "5px solid transparent",
borderBottom: "10px solid grey"
}}
onClick={() => increment(item.objectID)}
/>
</td>
<td>{ item.title }</td>
</tr>)
})
}
</table>
</td>
</tr>
</table>
);
}
export default TestLocalStorage;
但我注意到在第二次渲染时,localStorage 设置了初始值 [] 而不是新更新的值。不知道我要去哪里错了。 请帮助
storedData
将是字符串,您需要 JSON.parse(storedData)
才能使用它并对其执行 map
使用 JSON.parse()
对您从本地存储中提取的字符串进行解析function TestLocalStorage() {
const [items, setItems] = useState([]);
useEffect(() => {
const storedData = localStorage.getItem("items");
if(!storedData) {
Axios.get('/url').then(response => {
const serviceResponse = response.data.hits.map(obj=> ({ ...obj, voteCount: 0
}));
localStorage.setItem("items", JSON.stringify(serviceResponse));
setItems(serviceResponse);
});
} else {
setItems(storedData);
}
}, []);
...............
...............
...............
}
像下面那样修改你的函数。此外,在对数组进行映射操作之前检查项目值以防止未捕获的异常
function TestLocalStorage() {
const [items, setItems] = useState([]);
useEffect(() => {
const storedData = JSON.parse(localStorage.getItem("items"));
if(!storedData) {
Axios.get('/url').then(response => {
const serviceResponse = response.data.hits.map(obj=> ({ ...obj, voteCount: 0
}));
localStorage.setItem("items", JSON.stringify(serviceResponse));
setItems(serviceResponse);
});
} else {
setItems(storedData);
}
}, []);
...............
...............
...............
return (
.....
.....
items && items.map((item) => {
.....
.....
)
}