如何从 localStorage 设置 React 状态?
Posted
技术标签:
【中文标题】如何从 localStorage 设置 React 状态?【英文标题】:How to set React state from localStorage? 【发布时间】:2018-04-03 00:49:45 【问题描述】:我很难弄清楚如何使用 React 和 TS 从 localStorage 设置组件状态。在我检查 localStorage 实例是否存在后,它仍然说不兼容类型,因为localStorage.getItem()
仍然可以返回字符串或 null。
如果我更改界面并添加string | null
,我可以从localStorage 设置状态,但是我不再能够自行设置localStorage,因为localStorage.setItem()
似乎只接受string
而不是string | null
编辑
我想出了这个问题的“解决方案”。我不确定这是否是不好的做法,但它似乎有效。如果这可以写得更好,请告诉我。
componentWillMount()
let from = localStorage.getItem('from');
let to = localStorage.getItem('to');
let fromId = localStorage.getItem('fromId');
let toId = localStorage.getItem('toId');
if (typeof from === 'string' &&
typeof to === 'string' &&
typeof fromId === 'string' &&
typeof toId === 'string')
this.setState(
inputFrom: from,
inputTo: to,
fromId: fromId,
toId: toId,
);
编译错误:
类型参数 ' inputFrom: string |空值; ' 不可分配给“Pick”类型的参数。 属性“inputFrom”的类型不兼容。 键入'字符串 | null' 不可分配给类型 'string'。 类型 'null' 不能分配给类型 'string'。
我的接口实现如下:
interface State
inputFrom: string,
inputTo: string,
fromId: string,
toId: string,
tripdata: ,
loading: boolean,
error: boolean,
我的组件
import * as React from 'react';
import Header from './components/Header';
import SearchForm from './components/search/SearchForm';
import API from './api/APIService';
import TripTable from './components/trips/TripTable';
import Loading from './components/atoms/Loading';
import Error from './components/atoms/Error';
import './App.css';
const api = new API;
interface State
inputFrom: string,
inputTo: string,
fromId: string,
toId: string,
tripdata: ,
loading: boolean,
error: boolean,
class App extends React.Component<any, State>
constructor()
super();
this.state =
inputFrom: '',
inputTo: '',
fromId: '',
toId: '',
tripdata: ,
loading: false,
error: false,
;
componentWillMount()
let from = localStorage.getItem('from');
if (from !== null || from !== undefined)
this.setState(
inputFrom: from,
);
handleSubmit = () =>
if (this.state.fromId !== '' && this.state.toId !== '')
this.setState(error: false);
this.setState(loading: true);
api.GetAccessToken()
.then((token: string) =>
api.GetTripFromSearch(token, this.state.fromId, this.state.toId)
.then((res) =>
this.setState(
tripdata: res,
loading: false,
);
);
localStorage.setItem('from', this.state.inputFrom);
localStorage.setItem('to', this.state.inputTo);
localStorage.setItem('fromId', this.state.fromId);
localStorage.setItem('toId', this.state.toId);
);
else
this.setState(error: true);
render()
let triptable: JSX.Element | null;
let loading: JSX.Element | null;
let error: JSX.Element | null;
if (this.state.tripdata !== null)
triptable = <TripTable tripdata=this.state.tripdata />;
else
triptable = null;
if (this.state.loading)
loading = <Loading />;
triptable = null;
else
loading = null;
if (this.state.error)
error = <Error />;
else
error = null;
return (
<div>
<Header />
<SearchForm
resetInputId=this.resetInputId
handleInputFrom=this.handleInputFrom
handleInputTo=this.handleInputTo
handleSubmit=this.handleSubmit
error=error
handleSwap=this.handleSwap
/>
loading
triptable
</div>
);
export default App;
【问题讨论】:
我在您的代码中看不到任何Pick
类型,它来自哪里?你的代码在这篇文章中是最新的吗?
感谢您的回复。代码是最新的。确实很奇怪。我的代码中没有 Pick 之类的东西。但是我想我找到了解决问题的方法。也许丑陋,但它现在有效。
我认为你也可以在handleSubmit
中进行类型检查,但我不确定
这能回答你的问题吗? Argument of type 'string | null' is not assignable to parameter of type 'string'. Type 'null' is not assignable to type 'string'
您所要做的就是告诉编译器该值不为空。
【参考方案1】:
在我的具体情况下,我试图从本地存储中获取布尔值。本地存储不保存布尔值。所以如果你给它'true',它会将它保存为一个字符串。这就是 if 的用途。实际上,您可以使这个看起来更漂亮,但为了清楚起见,我在这里使用了 else if。
在这种情况下,我将 checkLocalStorage 函数放置在组件之外。我不明白为什么它在组件内部不起作用,但 this 帖子告诉我将它放在组件外部,所以我就是这样做的。
ps:如果本地存储中没有任何内容,则为空。这是我用来设置默认值的。
const checkLocalStorage = () =>
const ls = localStorage.getItem('item')
if (ls === null || ls === 'true')
return true
else if (ls === 'false')
return false
export const MyComponent = () =>
const [state, setState] = useState(checkLocalStorage())
// rest of your code here
【讨论】:
错字:第三行应该是if (ls === null || ls === 'true')
@edemaine 正确。我庆祝得太早了,没有彻底测试它,哈哈。谢谢你的纠正。实际上有没有一种方法可以做到这一点而不必输入 ls === 两次?因为我找不到。
不,这是最好的方法。您可以使用[null, 'true'].indexOf(ls) >= 0
,但这可能会慢一些。或者,您可以重组为 if (ls === 'false') return false else return true
,它的行为略有不同(但更多的是布尔值)。
@edemaine Huh,老实说看起来很干净。我应该偷那个。以上是关于如何从 localStorage 设置 React 状态?的主要内容,如果未能解决你的问题,请参考以下文章
React JS:从 localStorage 中删除一个项目