0

I'm trying to display checkbox ( that was already checked by the user) as checked after page refresh. I was able to save data of the selected rows in local storage (on check) and remove data on uncheck, but when I refresh the page checkbox displays as unchecked(even if local storage has the data stored in it).

My code is

import React, { useState, useEffect } from "react";

const data = [
  {
    id: "1",
    name: "Jane",
    lastName: "Doe",
    age: "25"
  },
  {
    id: "2",
    name: "James",
    lastName: "Doe",
    age: "40"
  },
  {
    id: "3",
    name: "Alexa",
    lastName: "Doe",
    age: "27"
  },
  {
    id: "4",
    name: "Jane",
    lastName: "Brown",
    age: "40"
  }
];

export default function App() {
  const [peopleInfo] = useState(
    data.map((d) => {
      return {
        select: false,
        id: d.id,
        name: d.name,
        lastName: d.lastName,
        age: d.age
      };
    })
  );

  const [peopleInfoValue, setPeopleInfoValue] = useState(
    localStorage.getItem("selectedPeople") == null
      ? ""
      : JSON.parse(localStorage.getItem("selectedPeople"))
  );

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

  return (
    <div className="App">
      <table>
        <tr>
          {peopleInfo?.map((d) => {
            return (
              <div
                key={d.id}
                style={{
                  display: "flex",
                  width: "150px"
                }}
              >
                <input
                  style={{ margin: "20px" }}
                  onChange={(e) => {
                    // add to list
                    let checked = e.target.checked;
                    if (checked) {
                      setPeopleInfoValue([
                        ...peopleInfoValue,
                        {
                          select: true,
                          id: d.id,
                          name: d.name,
                          lastName: d.lastName,
                          age: d.age
                        }
                      ]);
                    } else {
                      // to remove from localstorage
                      setPeopleInfoValue(
                        peopleInfoValue.filter((people) => people.id !== d.id)
                      );
                    }
                  }}
                  // checked={d.select}
                  type="checkbox"
                />
                <td style={{ margin: "20px" }}>{d.name}</td>
                <td style={{ margin: "20px" }}>{d.lastName}</td>
                <td style={{ margin: "20px" }}>{d.age}</td>
              </div>
            );
          })}
        </tr>
      </table>
    </div>
  );
}

and codeSandbox

As of now on box check local storage looks like this enter image description here

When I try to pass d.select to checked like this checked={d.select} ( so when d.select is === true box will be checked) it gets saved in localStorage as select:true but doesn't display checked on refresh. I can't figure out how to keep checked boxes still checked after page refresh. Any help and suggestions are greatly appreciated.

2
  • 1
    I fixed your code: codesandbox.io/s/gifted-noyce-0uq7i?file=/src/App.js (I also cleaned up the HTML and moved the checkbox change handler outside the JSX) Commented Mar 4, 2021 at 0:40
  • @Chris G, yes, that's exactly what I wanted to do. Thank you! Commented Mar 4, 2021 at 1:17

3 Answers 3

2

You've got the right idea, but there are errors in your code.

Your main problem is that when you render your component, you are mapping the values of peopleInfo, and when you're loading people to see which values have been checked before page refresh, you load them into peopleInfoValue, which you never actually reference when you're rendering your component. While you are correctly setting local storage, the values in local storage never make there way to the display.

Use @Chris G's version it does what you want and is very nice. It's good to understand why your original code wasn't working though.

Sign up to request clarification or add additional context in comments.

3 Comments

Since you posted this as answer you should at the very least fix the invalid HTML; other people might find this and paste it into their code.
@ChrisG it'd be nice if you pointed out which part of the html is invalid. I tested this and it worked with no errors, not sure how the HTML could be invalid. I think your solution is better btw, much cleaner, but it doesn't tell OP what he was doing wrong
@ChrisG Nevermind found what you're talking about. Thanks, I'm going to leave this up because it's the only answer actually explaining what OP does wrong
1

Problem

The list below shows the reasons why your checkbox doesn't update when the page refreshes.

  • checkbox status(checked) is only handled by onChange event (the status updates only when input value is changed by the UI)
  • useEffect only handles setting localStorage value

Solution

Include a method inside useEffect to do the following:

  • get localStorage value
  • set it to the state 'peopleInfoValue'

Comments

1

I see a lot of problems here.

First: you must need to check when you initialize your state if have something in the localstorage.

Second: every radio or checkbox input must have a conditional check in the property "checked":
<input name="IamCheckbox" type="checkbox" checked={user.select} />

Third: Have a lot forms to intialize this data. You can make a new var to pass to the useState or use the useEffect to check to you and update the state. If I doing this I will make the clear way as possible. Because maybe you had to format the data when you initialize the state.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.