简体   繁体   中英

How to get persist checkbox checked on page refresh in React JS?

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在此处输入图像描述

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.

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.

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'

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM