我目前有一个通过API呈现的动态列表项/ w折叠。
现在,我正在尝试将折叠状态(正确或错误/打开已关闭)保存在localstorage中,以便刷新页面时,我不会记住用户打开了什么折叠。
如何将动态状态保存在本地存储中?
您可以在下面看到我的代码
动态状态更改和本地存储保存
handleClick=(e, item)=>{
this.setState({
[item.id + 'Open'] : !this.state[item.id +'Open']
})
// store item details and jwt token in local storage to keep item logged in between page refreshes
localStorage.setItem('currentopentab', JSON.stringify(item));
currentUserSubject.next(item);
return item;
};
列表项
<List
component="nav"
subheader={<ListSubheader component="div">Waiting for order</ListSubheader>}
className={classes.root}
>
{
this.state.ordersWaiting.map((item, index) =>{
return (
<div key={index}>
{console.log('item',item)}
<ListItem button className={classes.orderheader} >
<div className={classes.expandContainer} onClick={((e) => this.handleClick(e, item))}>
<ListItemIcon>
<InboxIcon />
</ListItemIcon>
<ListItemText inset primary={item.userName} secondary={item.timeStamp}/>
{this.state[item.id + 'Open'] ? <ExpandLess /> : <ExpandMore />}
</div>
<Fab color="secondary" aria-label="Add" className={classes.fabButton}>
<AddIcon onClick={((e) => this.prepareOrder(e, item))} />
</Fab>
</ListItem>
<Collapse in={this.state[item.id + 'Open'] } timeout="auto" unmountOnExit>
<List component="div" disablePadding>
{ item.order.map((products, index) =>{
return (<ListItem key={index} button className={classes.nested}>
<ListItemIcon>
<StarBorder />
</ListItemIcon>
<ListItemText inset primary={products.qty + ' x ' + products.product} />
</ListItem>
)
}
)}
</List>
答案 0 :(得分:0)
这是我创建的本地存储类
LocalStorageService.js
class LocalStorageService {
constructor() {
this.uid = new Date;
this.storage = {};
this.storeable = false;
this.hasStorage();
if (this.storeable) {
this.storage = window.localStorage;
}
}
/**
* Verify that device has storage
*/
hasStorage() {
try {
(this.storage = window.localStorage).setItem(this.uid, this.uid);
this.storeable = this.storage.getItem(this.uid) !== this.uid;
this.storage.removeItem(this.uid);
this.storeable && (this.storage = false);
} catch (exception) {}
}
/**
* Return true if key exists
*/
has(key) {
return !_.isNull(this.get(key))
}
/**
* Get item from storage
*/
get(key) {
return this.storage.getItem(key);
}
/**
* Remove item from storage
*/
remove(key) {
this.storage.removeItem(key);
}
/**
* Save item to storage
*/
put(key,item) {
this.storage.setItem(key,item);
}
/**
*Update item in storage
*/
update(key,obj) {
this.remove(key);
this.save(key,obj)
}
/**
* Object to JSON string
*/
stringify(obj) {
return JSON.stringify(obj);
}
/**
* Parse JSON string back to JS
*/
parse(key) {
return JSON.parse(this.get(key));
}
/**
* Save object to storage
*/
save(key,obj) {
if (this.storeable) {
try {
this.storage.setItem(key,this.stringify(this.setItem(obj)));
} catch(e) {
this.remove(key);
}
}
}
}
export default LocalStorageService;
要在自己的类中使用它,请导入。
yourClassExample.js
import LocalStorageService from 'LocalStorageService';
class YourOwnClass {
constructor() {
this._storage = new LocalStorageService();
}
storeItem(storageKey,storageData) {
if (this._storage.isStoreable() && !this._storage.has(storageKey)) {
this._storage.save(storageKey,storageData);
}
}
}
您也可以将其设置为全局
import LocalStorageService from 'LocalStorageService';
window.$storage = new LocalStorageService();
答案 1 :(得分:0)
这是我的工作方式:我设置了一个状态为id
和open
的对象,以便可以轻松跟踪每个项目。
import React, { Component } from "react";
import { render } from "react-dom";
// this is your items array with many objects, I am using only id as for the illustration here
const items = [{ id: 1 }, { id: 2 }, { id: 3 }];
class App extends Component {
constructor() {
super();
this.state = {
itemState: []
};
}
componentDidMount() {
const itemState = localStorage.getItem("itemState");
itemState
? this.setState({ itemState: JSON.parse(itemState) })
: this.setItemState();
}
handleClick(id) {
const itemState = [...this.state.itemState];
itemState.forEach(item => item.id === id && (item.open = !item.open));
this.setState({ itemState });
localStorage.setItem("itemState", JSON.stringify(itemState));
}
setItemState() {
let itemState = [];
// this items is what you fetched from the backend
// setting id and open flag to track the open status for each item
items.forEach(item => {
itemState.push({ id: item.id, open: false });
});
this.setState({ itemState });
localStorage.setItem("itemState", JSON.stringify(itemState));
}
isItemOpen(id) {
const { itemState } = this.state;
const currentItem = itemState.filter(item => item.id === id)[0];
return currentItem ? currentItem["open"] : false;
}
render() {
return (
<div>
<pre>{JSON.stringify(this.state, null, 4)}</pre>
{items.map(item => {
return this.isItemOpen(item.id) ? (
<div id={item.id}>
ID: {item.id} <br />
Open: Open <br />
Other content <br />
<button onClick={() => this.handleClick(item.id)}> Change</button>
<hr />
</div>
) : (
<div>
{" "}
The Div with id {item.id} is Closed now{" "}
<button onClick={() => this.handleClick(item.id)}> Change</button>
</div>
);
})}
</div>
);
}
}
render(<App />, document.getElementById("app"));