Somi
Somi

Reputation: 141

How to store state that has component in localStorage?

I'm trying to store some value in local storage, so I tried to set the functional chart state to change component into localStorage and it got an error.

error

TypeError: Converting circular structure to JSON

and chart state looks like this:

const [chart, setChart] = useState([
    empty,
    empty,
    empty,
    empty,
    empty,
    empty,
    empty,
    empty,
  ]);
  
  /////////////////empty //////////////
  export const empty = <Bar />;
And I'm using this state like this:

 const updateChart = index => chartType => () => {
    setChart(charts =>
      charts.map((chart, i) => (i === index ? chartType : chart))
    );
    
    
    
    ////chartType///// 
    
     const chartType = index => [
    <Bar
      key="Bar"
      data={DataContext[index]}
      options={{
        responsive: true,
        maintainAspectRatio: false,
        plugins: plugins[index],
      }}
    />,
    <Line
      key="Line"
      data={DataContext[index]}
      options={{
        responsive: true,
        maintainAspectRatio: false,
        plugins: plugins[index],
      }}
    />,
    ....
    ...
this is how i set and get item on localStorage :

 useEffect(() => {
    const persistChart = localStorage.getItem("chart");
    if (persistChart) {
      setChart(JSON.parse(persistChart));
    }
  }, []);

  useEffect(() => {
    localStorage.setItem("chart", JSON.stringify(chart), [chart]);
  });

So that way didn't work , so I tried to get the key from the chart state and make new useState with chart's key

like this :

  const [chart, setChart] = useState([
        empty,
        empty,
        empty,
        empty,
        empty,
        empty,
        empty,
        empty,
      ]);
      const [chartKey, setChartKey] = useState([
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
      ]);
      
        useEffect(() => {
    const persistChart = localStorage.getItem("chart");
    if (persistChart) {
      setChartKey(JSON.parse(persistChart));
    }
  }, []);

  useEffect(() => {
    localStorage.setItem("chart", JSON.stringify(chartKey), [chartKey]);
  });
  
  ///////// function/////
      const updateChart = index => chartType => () => {
   setChart(charts =>
  charts.map((chart, i) => (i === index ? chartType : chart))
   );
   setChartKey(charts =>
    charts.map((chart, i) => (i === index ? chartType.key : chart))
   );
   };

However, I was rendering the chart on a component like this: {chart[0]} ... {chart[1]} ... {chart[2]}

But localStorage didn't work so I'm trying to use chartKey state with chart.

I can get and set chartKey using localstorage but the thing is i just only can render chart.key

I can't figure out how to render chart using chartKey

and I wonder if there is another way to store the functional state and if the way I did was right.

Thank you so much in advance

Upvotes: 0

Views: 37

Answers (1)

hasankzl
hasankzl

Reputation: 1019

You need to pass 2 param to localStorage.setItem function see this:

localStorage.setItem("chart", JSON.stringify(chart));

after that you can directly call the localstorage inside the useState,

 // you need the define this getCharts function before useState,
 // or you can use useEffect for same thing
       const getCharts = () => {
    // get charts from localStroge
    let chartList = JSON.parse(localStorage.getItem("chart"));

    // empty check
    if (!chartList) {
      chartList = [
        "empty",
        "empty",
        "empty",
        "empty",
        "empty",
        "empty",
        "empty",
        "empty",
      ];
    }

    return chartList;
  }
  const [chart, setChart] = useState(() => getCharts());

Upvotes: 1

Related Questions