英文:
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>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论