gpt4 book ai didi

javascript - 如何将本地存储添加到我的React.js应用程序?

转载 作者:行者123 更新时间:2023-12-01 01:22:07 25 4
gpt4 key购买 nike

我有一个应用程序-待办事项列表,其中包含存储列表项,评论,评论数等不同项目的评论。

您能帮我将localStorage添加到我的应用中,以便将所有项目保存到localStorage吗?

我读过一篇文章,说我们需要设置2个变量的路径:键和对象。我如何通过所有物品的整个状态?

这是代码:

App.js

import React, { Component } from 'react';
import './App.css';
import ListInput from './components/listInput'
import ListItem from './components/listItem'
import SideBar from './components/sideBar'
import CommentsSection from './components/commentsSection'

class App extends Component {
constructor(props){
super(props);

this.state = {
items: [
{
id: 1,
title: 'First item',
commentsCount: 0,
comments: [],
displayComment: false
},
{
id: 2,
title: 'Second item',
commentsCount: 0,
comments: [],
displayComment: false
},
{
id: 3,
title: 'Third item',
commentsCount: 0,
comments: [],
displayComment: false
},
],
activeItem: {},
isHidden: true
}
}
// Add new item to the list
addItem = inputText => {
let itemsCopy = this.state.items.slice();
itemsCopy.push({id: this.state.items.length + 1, title: inputText, commentsCount: 0, comments: [], displayComment: false});

this.setState({
items: itemsCopy,
})
}
// Remove the item from the list: check if the clicked button id is match
removeItem = id =>
this.setState({
items: this.state.items.filter((item, index) => item.id !== id)
})

addComment = (inputComment) => {
// find item with id passed and select its comments array
const commentCopy = this.state.items.map(item => {
if (item.id === this.state.activeItem.id) {
return {
...item,
commentsCount: item.comments.length + 1,
comments: item.comments.concat({id: item.comments.length + 1, text: inputComment})
}
}
return item
});
this.setState({
items: commentCopy
})
}

getActiveItem = () => this.state.items.find(item => item.id === this.state.activeItem.id)

render() {
console.log(this.state.items.isHidden)
return (
<div className='App'>
<SideBar />
<div className='flex-container'>
<div className='list-wrapper'>
<h1>Items</h1>
<ListInput inputText='' addItem={this.addItem}/>
<ul>
{
this.state.items.map((item) =>
(<ListItem
item={item}
key={item.id}
id={item.id}
removeItem={this.removeItem}
setActiveComment={() => this.setState({ activeItem: item })}
toggleHidden={() => this.setState({ isHidden: false })}
/>
))
}
</ul>
</div>
<div>
{!this.state.isHidden && <CommentsSection
addComment={this.addComment}
activeItem={this.getActiveItem()}
/>}
</div>
</div>
</div>
);
}
}
export default App;


commentSection.js

import React from 'react';
import CommentInput from './commentInput'
import CommentsItem from './commentsItem'
import './commentsSection.css';

export default class CommentsSection extends React.Component {
constructor(props){
super(props);
this.state = {value: ''};
}

handleChange = event => this.setState({value: event.target.value})

handleEnter = event => {
if (event.charCode === 13 && event.ctrlKey) {
console.log(this.state, this.props)
this.addComment(this.state.value)
}
}

addComment = comment => {
console.log(this.props.activeComment)
// Ensure the comment text isn't empty
if (comment.length > 0) {
this.props.addComment(comment);
this.setState({value: ''});
}
}

render() {
return (
<div className='component-section'>
<h1>{this.props.activeItem && this.props.activeItem.title}</h1>
<ul>
{ this.props.activeItem &&
this.props.activeItem.comments.map((comment) => <p key={comment.id}>{comment.text}</p>)
}
</ul>
{/*<CommentsItem />*/}
{/*<CommentInput addComment={this.addComment}/>*/}
<div className='comment-input'>
<input type='text' value={this.state.value} onChange={this.handleChange} onKeyPress={this.handleEnter}/>
</div>
</div>
)
}
}


listInput.js

import React from 'react';
import './listInput.css'

export default class ListInput extends React.Component {
constructor(props){
super(props);
this.state = {value: this.props.inputText};

this.handleChange = this.handleChange.bind(this);
this.addItem = this.addItem.bind(this);
}

handleChange = event => this.setState({value: event.target.value})

addItem(item) {
// Ensure the todo text isn't empty
if (item.length > 0) {
this.props.addItem(item);
this.setState({value: ''});
}
}

render() {
return (
<div className='list-input'>
<input type='text' value={this.state.value} onChange={this.handleChange} placeholder={'Type name here...'}/>
<button className='btn btn-primary' onClick={() => this.addItem(this.state.value)}>Add new</button>
</div>
)
}
}

最佳答案

简单说明:

localStorage有两种重要方法:


localStorage.setItem(*name*,*string value*)


参数name只是您希望存储在存储中以轻松引用数据的键。
参数string value只是您希望存储在key/name下的存储中的值。重要的是它必须是一个字符串。 localStorage无法存储数组和/或对象

localStorage.getItem(*name*)


唯一需要的参数是name,它是先前为name设置的setItem
如果key/namelocalStorage中不存在,则返回null;如果确实存在,则返回字符串值。



为什么这些事情很重要?状态是一个对象。让我们创建一个小版本:

let state = { name: "zak" };


如前所述,您不能在 localStorage中存储字符串以外的任何内容。那我们该怎么办呢?我们要存储状态,对不对?好吧...我们必须将我们的对象转置为字符串。

我们可以使用 JSON方法做到这一点:


JSON.stringify(**object or array**)


这将简单地接受任何传入的对象或数组并将其转换为字符串。

JSON.parse(**string**)


这将采用任何字符串,并尝试使用JavaScript对其进行重新评估,以将其转换为对象或数组。



我们有一个状态对象,在使用 localStorage.setItem保存之前,需要将其转换为字符串。为此,我们使用 JSON.stringify

使用 localStorage.getItem时,我们将以字符串形式接收状态对象的表示形式,在将其用于应用程序之前,需要将其转换为状态对象。为此,我们使用 JSON.parse



保存的代码示例:

let state = { name: "zak" };

let state_string = JSON.stringify(state);

localStorage.setItem("my_saved_state", state_string);


上面的代码将处于状态,将其转换为字符串并保存。要进行相反的操作,我们只需要获取字符串并将其变回一个对象即可。



LOADING的代码示例:

let state = { name: "zak" };

let state_string = JSON.stringify(state);

localStorage.setItem("my_saved_state", state_string);

let returned_state_string = localStorage.getItem("my_saved_state");

let returned_state_object = JSON.parse(returned_state_string);


上面的结果是:

console.log(returned_state_object); // { name: "zak" }
console.log(state); // { name: "zak" }


如您所见,您已经有效地从 localStorage保存和加载了。



更彻底,更深入的解释:

使用 setItem API的 getItemlocalStorage方法。

然后可以使用 name和通过 JSON.stringify的字符串化对象进行保存。这很重要,因为 storage api仅允许保存字符串。没有对象文字,没有数组等。

然后,您可以通过引用 name并通过 JSON.parse解析返回的String来加载。这将有效地将字符串重新水化为原始的对象/数组形式。

重要说明:存储在 state中的对象或数组中的任何引用在转置为字符串时都会中断。显然,字符串不能作为引用,所以这很有意义。为了解决这个问题,您可以创建一个解析器来重新设计引用,但这超出了此答案的范围。



我会承认一点意见,但我认为这是一个备受赞誉的观点,那就是在使用Storage API时最好使用函数,因为它可以使编码更加清晰。以下是保存状态,加载状态以及测试保存和加载状态是否相同以证明其概念的示例。

重要说明:您会注意到,在加载函数中,我们首先在 raw_data中接收数据-这是因为如果密钥不存在(即第一次运行程序,则不会保存)数据),它将返回 null。这是一个简单的健全性检查,如果不存在空对象,它将返回一个空对象-在您的情况下,您可能想抛出一个错误,但这取决于您。

它会显示StackOverflow不允许使用存储,因此,如果您想查看运行的版本,请查看此随附的 fiddle

let state = {
items: [{
id: 1,
title: 'First item',
commentsCount: 0,
comments: [],
displayComment: false
},
{
id: 2,
title: 'Second item',
commentsCount: 0,
comments: [],
displayComment: false
},
{
id: 3,
title: 'Third item',
commentsCount: 0,
comments: [],
displayComment: false
},
],
activeItem: {},
isHidden: true
}


function saveAs(name, state_obj) {
let data = JSON.stringify(state_obj);
localStorage.setItem(name, data);
console.log("saved!");
}

function loadFrom(name) {
let raw_data, data;
raw_data = localStorage.getItem(name);
if (!raw_data) return {};
data = JSON.parse(raw_data);
return data;
}

function test(_old, _new) {
return JSON.stringify(_old) === JSON.stringify(_new);
}

saveAs("my_saved_state", state);
let myNewState = loadFrom("my_saved_state");

console.log( test(state, myNewState) ? "old and new are the same!" : "old and new are different" );

关于javascript - 如何将本地存储添加到我的React.js应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54135796/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com