reactjs - 如何在 ToDo App 中渲染本地存储中的每个项目
问题描述
如何渲染本地存储中的所有项目并在每次渲染后将它们显示为反应组件?我正在尝试制作一个 toDo 应用程序,我试图将用户键入的数据缓存到复选框中。
每当用户离开页面并返回时,他们之前在复选框中键入的数据仍会显示。我已经部分解决了这个问题,但我在这里遇到的问题是无法将本地存储中的所有项目显示为 useEffect 中的反应组件。有什么好的解决方案可以解决这个问题?
**Tasks.JSX**
import React, {useState, useEffect} from "react";
import {Delete, Refresh, Add} from "../components/Actions";
import {Header} from "../components/Header";
import {PriorityLists} from "../components/PriorityLists";
import {v4 as uuidv4} from 'uuid';
import { serialize, deserialize } from "react-serialize";
function Task() {
const [toDo, setToDo] = useState([])
const [idsToRefresh, setIdsToRefresh] = useState([]);
const [filter_items, setFilterItems] = useState(false);
const [ids, setIds] = useState([]);
const [text, setTextValue] = useState({key:null, txt:null});
useEffect(()=> {
for(let i=0; i < localStorage.length; i++) {
let storedValue = localStorage.key(i);
let value = JSON.parse(localStorage.getItem(storedValue));
if(typeof value === "string") {
setToDo(toDo.concat({_Id: storedValue, item_value: <PriorityLists id = {storedValue} checked = {false} addIds = {addIds} local_storage ={ls} text_value = {value} />}));
console.log(`${value} Index ${i}`);
}
}
}, [])
useEffect(() => {
if(toDo[0] !== undefined) {
setToDo(toDo.filter(item=> {
return !ids.includes(item._Id);
}))
}
}, [filter_items]);
function addIds(checked, id_to_be_deleted) {
if(!checked) {
setIds((item)=> [...item, id_to_be_deleted]);
}
else {
setIds(ids.filter(item=> {
return item !== id_to_be_deleted;
}))
}
}
function ls(e) {
localStorage.setItem(JSON.stringify(e.target.id), serialize(e.target.value));
}
function addToDos() {
const id = uuidv4();
setToDo(toDo.concat({_Id: id, item_value: <PriorityLists id = {id} checked = {false} addIds = {addIds} local_storage ={ls} text_value = {null} />}));
setIdsToRefresh(idsToRefresh.concat(id));
}
function refresh() {
setToDo(toDo.filter(item=> {
return !idsToRefresh.includes(item._Id);
}))
}
return (
<div className = "main-content">
<div className = "container-fluid">
<div className = "row underline">
<div className= "col">
<div className = "row">
<div className = "col-3 pt-2">
<Refresh _refresh = {refresh} />
</div>
<div className = "col-6 text-center">
<Header header ={"Tasks"}/>
</div>
<div className = "col-3 pt-2">
<button className = "float-right">
<Delete setFilterItems = {setFilterItems} filter = {filter_items} />
</button>
</div>
</div>
</div>
</div>
<div className = "row">
<div className = "col">
{
toDo.map(item=> {
return (<div key = {item._Id}>
<ul>
<li>{item.item_value}</li>
</ul>
</div>)
})}
</div>
</div>
<div className = "row">
<div className = "col pr-4">
<Add addToDos = {addToDos} />
</div>
</div>
</div>
</div>
)
}
export default Task;
PriorityLists.jsx
import React, {useState, useEffect} from "react";
import { Priority } from "./Actions";
function PriorityLists(props) {
const [isChecked, setChecked] = useState(false);
const [changeInput, setChangeInput] = useState(props.text_value);
function check(e) {
const id_to_be_deleted = e.target.attributes.getNamedItem("unique_Key").value;
if(!isChecked) {
setChecked(true);
props.addIds(isChecked, id_to_be_deleted);
}
else {
setChecked(false);
props.addIds(isChecked, id_to_be_deleted)
}
}
function setChange(e) {
setChangeInput(e.target.value);
props.local_storage(e);
}
return (
<form key = {props.id} >
<div className = "input-group mb-3">
<div className="input-group-prepend">
<div className="input-group-text">
<input unique_Key = {props.id} onInput = {e=> e.target.checked = isChecked} onClick={e=> check(e) } checked = {props.checked} id = "check-item" type="checkbox" aria-label="Checkbox for following text input"/>
</div>
</div>
<textarea id = {props.id} onChange = {e=>setChange(e)} value = {changeInput} class="form-control" rows="1" name = {props.name}></textarea>
<Priority id = {props.id} text_value = {changeInput} />
</div>
</form>
)
}
export {PriorityLists};
解决方案
一种方法是向存储事件添加事件侦听器,该事件侦听器每次都会触发函数调用。
Vo 提到了一种处理存储事件的方法。
如果您从初始挂载的存储中加载数据,并将其存储在跨组件共享的上下文中,我个人会更喜欢。
通过这种方式,您可以直接更新状态,并且作为副作用,您也可以更新 localStorage。
在我看来,这是一种更清洁的方法。
saveData
loadData
在 localStorage 的 utils 函数中创建- 使用 key 加载数据,并在 AppContext 中存储为 initState
- 跨视图共享状态。
- 更新状态
- 添加带有状态的 useEffect,并在状态更新时保存数据
我希望这能解决你的问题
推荐阅读
- instagram - Instagram API - https://instagram.api-docs.io/
- amazon-web-services - RDS 子网组更改错误“不能与 RDS 在同一 VPC 上”
- html - HTML 和 CSS 响应能力
- python - 如何在python中按住一个键并立即释放?
- html - ReactJS:导航栏当前页面效果
- scala - 将函数作为参数、元组或具有两个参数的函数传递
- javascript - 如何更改我的 html 脚本以运行命令行命令
- python-3.x - 如何解决模块'pandas'没有属性'scatter_matrix'属性错误
- node.js - 如何测试猫鼬会话事务。错误:MongooseError:连接 1 在调用`startSession 时断开连接
- javascript - 使用箭头函数时封闭词汇上下文的含义(词汇 this)