React why does my useEffect hook that retrieves local storage break after wrapping my state in context?

huangapple go评论90阅读模式
英文:

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&#39;m receiving an error upon load that reads &quot;JSON.parse: unexpected character at line 1 column 1 of the JSON data&quot;. I believe the issue is directly related to where the useEffect hook is placed but I&#39;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.

&lt;ReptileContext.Provider value={{ ... }}&gt;&lt;/ReptileContext.Provider&gt;

huangapple
  • 本文由 发表于 2023年7月20日 18:05:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76728774.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定