英文:
React why does my useEffect hook that retrieves local storage break after wrapping my state in context?
问题
以下是您要翻译的代码部分:
My working code before converting all my state into context:
**App.js**
```javascript
function App() {
const [reptile, setReptile] = useState(function () {
const storedValue = localStorage.getItem("reptiles");
return JSON.parse(storedValue);
})...
...useEffect(
function () {
localStorage.setItem("reptiles", JSON.stringify(reptile));
},
[reptile]
);
My current code:
Context.js
const ReptileContext = createContext();
function ReptileProvider({ children }) {
const [reptile, setReptile] = useState(function () {
const storedValue = localStorage.getItem("reptiles");
return JSON.parse(storedValue);
});
const [daysFed, setDaysFed] = useState("");
const [displayForm, setDisplayForm] = useState(false);
const [displayList, setDisplayList] = useState(true);
const [displayReptile, setDisplayReptile] = useState(false);
const [selectedReptile, setSelectedReptile] = useState(null);
const [today, setToday] = useState(null);
const [reptileType, setReptileType] = useState("");
const [reptileName, setReptileName] = useState("");
const [notes, setNotes] = useState("");
function handleAddReptile(reptile) {
setReptile((reptiles) => [...reptiles, reptile]);
}
function handleDeleteReptile(reptileId) {
setReptile((reptiles) => reptiles.filter((rep) => rep.id !== reptileId));
}
function handleSelection(reptileId) {
setSelectedReptile(reptileId);
setDisplayList(false);
setDisplayReptile(true);
}
function handleBack() {
setDisplayReptile(false);
setDisplayList(true);
}
return (
<ReptileContext.Provider
value={{
reptile,
reptileType,
setReptileType,
reptileName,
setReptileName,
notes,
setNotes,
daysFed,
setDaysFed,
displayForm,
setDisplayForm,
displayList,
setDisplayList,
displayReptile,
setDisplayReptile,
selectedReptile,
setSelectedReptile,
today,
setToday,
handleAddReptile,
handleDeleteReptile,
handleSelection,
handleBack,
}}
>
{children}
</ReptileContext.Provider>
);
}
function useReptile() {
const context = useContext(ReptileContext);
if (context === undefined)
throw new Error("PostContext was used outside of the PostProvider");
return context;
}
export { ReptileProvider, useReptile };
App.js
function App() {
const { displayForm, displayList, displayReptile, selectedReptile, reptile } =
useReptile();
useEffect(
function () {
if (!reptile) return;
localStorage.setItem("reptiles", JSON.stringify(reptile));
},
[reptile]
);
index.js
<ReptileProvider>
<App />
</ReptileProvider>
I'm receiving an error upon load that reads "JSON.parse: unexpected character at line 1 column 1 of the JSON data". I believe the issue is directly related to where the useEffect hook is placed but I'm not entirely sure. Any help would be greatly appreciated, thanks!
<details>
<summary>英文:</summary>
My working code before converting all my state into context:
**App.js**
function App() {
const [reptile, setReptile] = useState(function () {
const storedValue = localStorage.getItem("reptiles");
return JSON.parse(storedValue);
})...
...useEffect(
function () {
localStorage.setItem("reptiles", JSON.stringify(reptile));
},
[reptile]
);
My current code:
**Context.js**
const ReptileContext = createContext();
function ReptileProvider({ children }) {
const [reptile, setReptile] = useState(function () {
const storedValue = localStorage.getItem("reptiles");
return JSON.parse(storedValue);
});
const [daysFed, setDaysFed] = useState("");
const [displayForm, setDisplayForm] = useState(false);
const [displayList, setDisplayList] = useState(true);
const [displayReptile, setDisplayReptile] = useState(false);
const [selectedReptile, setSelectedReptile] = useState(null);
const [today, setToday] = useState(null);
const [reptileType, setReptileType] = useState("");
const [reptileName, setReptileName] = useState("");
const [notes, setNotes] = useState("");
function handleAddReptile(reptile) {
setReptile((reptiles) => [...reptiles, reptile]);
}
function handleDeleteReptile(reptileId) {
setReptile((reptiles) => reptiles.filter((rep) => rep.id !== reptileId));
}
function handleSelection(reptileId) {
setSelectedReptile(reptileId);
setDisplayList(false);
setDisplayReptile(true);
}
function handleBack() {
setDisplayReptile(false);
setDisplayList(true);
}
return (
<ReptileContext.Provider
value={
(reptile,
reptileType,
setReptileType,
reptileName,
setReptileName,
notes,
setNotes,
daysFed,
setDaysFed,
displayForm,
setDisplayForm,
displayList,
setDisplayList,
displayReptile,
setDisplayReptile,
selectedReptile,
setSelectedReptile,
today,
setToday,
handleAddReptile,
handleDeleteReptile,
handleSelection,
handleBack)
}
>
{children}
</ReptileContext.Provider>
);
}
function useReptile() {
const context = useContext(ReptileContext);
if (context === undefined)
throw new Error("PostContext was used outside of the PostProvider");
return context;
}
export { ReptileProvider, useReptile };
**App.js**
function App() {
const { displayForm, displayList, displayReptile, selectedReptile, reptile } =
useReptile();
useEffect(
function () {
if (!reptile) return;
localStorage.setItem("reptiles", JSON.stringify(reptile));
},
[reptile]
);
**index.js**
<ReptileProvider>
<App />
</ReptileProvider>
I'm receiving an error upon load that reads "JSON.parse: unexpected character at line 1 column 1 of the JSON data". I believe the issue is directly related to where the useEffect hook is placed but I'm not entirely sure. Any help would be greatly appreciated, thanks!
</details>
# 答案1
**得分**: 2
我认为问题不在于`useEffect`钩子,而在于您将值传递给`ReptileContext.Provider`的方式。您使用的是括号而不是花括号,这意味着您传递的是单个表达式而不是对象。这可能会导致在尝试读取存储的值时`JSON.parse`失败。
```jsx
<ReptileContext.Provider value={{ ... }}></ReptileContext.Provider>
英文:
I think the problem is not with the useEffect
hook, but with the way you are passing the value to the ReptileContext.Provider
. You are using parentheses instead of curly braces, which means you are passing a single expression instead of an object. This might cause the JSON.parse
to fail when trying to read the stored value.
<ReptileContext.Provider value={{ ... }}></ReptileContext.Provider>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论