javascript - Object is possibly null error (typescript) when trying to display the value of an array which is stored in localsto

I'm currently creating a weather app where you can store your favorite locations which are pushed

I'm currently creating a weather app where you can store your favorite locations which are pushed to an array, which in turn is stored in localstorage.

Now, I want to display the values of the array in a different ponent, but with my code I keep stumbling upon the error that the object is possible null.

export const FavoritesList: React.FC<any> = () => {
  // const storageFavorites = localStorage.getItem('favorites');
  const lsOutput = document.getElementById('lsOutput');
  for (let i = 0; i < localStorage.length; i++) {
    const key: any = localStorage.key(i);
    const value: any = localStorage.getItem(key);
    // console.log(value);
    value.forEach(
      (item: any) => (lsOutput.innerHTML += `<li>${item}</li><br/>`)
    );
  }
  return (
    <div>
      <ul id="lsOutput"></ul>
    </div>
  );
};

and it points specifically at lsOutput.innerHTML

What am I doing wrong? I've currently assigned everything as any just to try to make it work first. Thank you very much in advance!

I'm currently creating a weather app where you can store your favorite locations which are pushed to an array, which in turn is stored in localstorage.

Now, I want to display the values of the array in a different ponent, but with my code I keep stumbling upon the error that the object is possible null.

export const FavoritesList: React.FC<any> = () => {
  // const storageFavorites = localStorage.getItem('favorites');
  const lsOutput = document.getElementById('lsOutput');
  for (let i = 0; i < localStorage.length; i++) {
    const key: any = localStorage.key(i);
    const value: any = localStorage.getItem(key);
    // console.log(value);
    value.forEach(
      (item: any) => (lsOutput.innerHTML += `<li>${item}</li><br/>`)
    );
  }
  return (
    <div>
      <ul id="lsOutput"></ul>
    </div>
  );
};

and it points specifically at lsOutput.innerHTML

What am I doing wrong? I've currently assigned everything as any just to try to make it work first. Thank you very much in advance!

Share Improve this question asked Apr 8, 2020 at 10:36 jrwebbiejrwebbie 992 silver badges12 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 6

TypeScript is warning you that getElementById can return null (if there's no element with that ID). If you know that the element will exist, you an reassure TypeScript with a non-null assertion:

const lsOutput = document.getElementById('lsOutput')!;
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^

(But I don't think you do know that, see under the bar below.)

You'll have the same problem later with value. The analysis TypeScript does isn't deep enough to know that you're getting key from localStorage.key(i) and so you know localStorage.getItem(key) will return a non-null value. So again, you have to tell it that:

const value: any = localStorage.getItem(key)!;
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^

But there's another problem: value.forEach will never be defined in that code. localStorage only stores strings, not arrays, and strings don't have a forEach method.

When I want to store plex data in localStorage, I use JSON. For instance:

// Storing an array (or object)
localStorage[key] = JSON.stringify(theArray);

// Retrieving:
const theArray = JSON.parse(localStorage[key]);

You're trying to work directly with the DOM within a React ponent, which is rarely necessary. When it is necessary, the way you're doing it isn't best practice (and won't work unless you already have a different element with the ID lsOutput, in which case you're creating a DOM with an invalid structure — you can't have two elements with the same id value). When your ponent function runs, the output you return from it won't be in the DOM yet.

Instead, do it the React way:

export const FavoritesList: React.FC<any> = () => {
  const items = [];
  for (let i = 0; i < localStorage.length; i++) {
    const key: any = localStorage.key(i);
    const value: any = localStorage.getItem(key);
    items.push(value);
  }
  return (
    <div>
      <ul>{items.map(item => <li>{item}</li>}</ul>
    </div>
  );
};

I'd also remend using a single storage entry to hold that array of items, using JSON as shown above:

export const FavoritesList: React.FC<any> = () => {
  const items: string[] = JSON.parse(localStorage.getItem("favorites"))!;
  return (
    <div>
      <ul>{items.map(item => <li>{item}</li>}</ul>
    </div>
  );
};

It might also make sense not to go to local storage every time the ponent function is called; perhaps load the items in a parent ponent and pass them down as props.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745390188a4625625.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信