简体   繁体   English

尝试显示存储在 localstorage 中的数组的值时,Object 可能是 null 错误(打字稿)

[英]Object is possibly null error (typescript) when trying to display the value of an array which is stored in localstorage

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 component, but with my code I keep stumbling upon the error that the object is possible null.现在,我想在不同的组件中显示数组的值,但是在我的代码中,我不断发现 object 可能是 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它专门指向 lsOutput.innerHTML

What am I doing wrong?我究竟做错了什么? I've currently assigned everything as any just to try to make it work first.我目前已将所有内容分配为 any 只是为了使其首先工作。 Thank you very much in advance!非常感谢您!

TypeScript is warning you that getElementById can return null (if there's no element with that ID). TypeScript 警告您getElementById可以返回null (如果没有具有该 ID 的元素)。 If you know that the element will exist, you an reassure TypeScript with a non- null assertion :如果您知道该元素将存在,请使用null断言向 TypeScript 保证:

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 .稍后您将遇到与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. TypeScript 所做的分析不够深入,无法知道您正在从localStorage.key(i)获取key ,因此您知道localStorage.getItem(key)将返回非null值。 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.但是还有另一个问题: value.forEach永远不会在该代码中定义。 localStorage only stores strings, not arrays, and strings don't have a forEach method. localStorage存储字符串,不存储 arrays,并且字符串没有forEach方法。

When I want to store complex data in localStorage , I use JSON.当我想在localStorage中存储复杂数据时,我使用 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 component, which is rarely necessary.您正在尝试在 React 组件中直接使用 DOM,这很少需要。 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).必要时,您的操作方式不是最佳实践(除非您已经有一个 ID lsOutput不同元素,否则您将无法使用,在这种情况下,您正在创建一个具有无效结构的 DOM - 您不能有两个具有相同id值的元素)。 When your component function runs, the output you return from it won't be in the DOM yet.当您的组件 function 运行时,您从它返回的 output 还不会在 DOM 中。

Instead, do it the React way:相反,用 React 的方式来做:

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 recommend using a single storage entry to hold that array of items, using JSON as shown above:我还建议使用单个存储条目来保存该项目数组,使用 JSON,如上所示:

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 component function is called;每次调用组件 function 时,不要将 go 放到本地存储中也可能有意义; perhaps load the items in a parent component and pass them down as props.也许将项目加载到父组件中并将它们作为道具传递。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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