Home > Net >  React - Display all items inside localStorage as a Material UI List
React - Display all items inside localStorage as a Material UI List

Time:02-21

I have localStorage with multiple items on it. I want to retrieve all of them and display it on a <ListItem> Material UI.

Here's my current code:

function saveJob(key, value) {
  localStorage.setItem(key, value);
}

function saveJob is basically just save the value along with unique key. The content of the localStorage would be something like this:

Key Value
1 Technician
2 Plumber

How I retrieved the items back:

var savedJobs = [];
useEffect(() => {
    var keys = Object.keys(localStorage),
        i = keys.length;

    while (i--) {
        savedJobs.push(localStorage.getItem(keys[i]));
    }

    return savedJobs;
}, [])

Now onto the problem, I tried to display it in a functional component through <ListItem> Material UI like the following:

<List>
    {savedJobs.map((job) => (
    <ListItem key={job.Key} disablePadding>
    <ListItemButton>
      <ListItemText  primary={job.Value} />
    </ListItemButton>
  </ListItem>
    ))}
</List>

This is not working. Can anyone point me in the right direction?

CodePudding user response:

React doesn't trigger rerender when a local variable in a function component was changed. It will be rerendered when: the state has changed, props were changed or the parent component was rerendered.

You should put your savedJobs to state and write

const [savedJobs, setSavedJobs] = useState([]);

instead of

var savedJobs = [];

CodePudding user response:

You need state to store the data you retrieve from localstorage. Instead of your savedJobs var outside of your useEffect, create an array inside the hook and then update your state with this data. Here's an example:

  // Initiate your state as an empty array.
  const [savedJobs, setSavedJobs] = useState([]);

  // Used as an example instead of localstorage.
  const example = ["foo", "bar"];

  useEffect(() => {
    let jobs = [];
    let keys = Object.keys(example),
      i = keys.length;
    while (i--) {
      jobs.push(example[i]);
    }
    setSavedJobs(jobs);
  }, [example]);

  return <>{savedJobs.map((job) => job)}</>;

Or see this interactive example.

CodePudding user response:

First I would check what is inside your savedJobs array. It seems that savedJobs would look like this:

savedJobs = ['Technician', 'Plumber'];

On the other hand, you are mapping and getting the value like so: {job.Key} & {job.Value}

Try:

<List>
    {savedJobs.map((job, i) => (
    <ListItem key={i} disablePadding>
    <ListItemButton>
      <ListItemText  primary={job} />
    </ListItemButton>
  </ListItem>
    ))}
</List>

ps: you should not use i as a key, but I let you figuring out what value you want there.

If you want to use {job.key} and {job.value}, you need to push an object like so:

  
  savedJobs.push({key: i, value: localStorage.getItem(keys[i])});

  • Related