为什么要删除localStorage中的React状态



我在本地存储中持久化状态时遇到了问题。这是一个简单的待办事项应用程序。添加一个待办事项并刷新后,所有待办事项都会被删除。不知道为什么。以下是相关代码:

const [ todos, setTodos ] = useState([])
useEffect(() => {                                                                                                         
│   │   console.log('b1:',JSON.parse(localStorage.todos))                                                                     
│   │   if (localStorage.todos !==null) {                                                                                     
│   │   │   console.log(JSON.parse(localStorage.todos))                                                                       
│   │   │   setTodos(JSON.parse(localStorage.todos))                                                                          
│   │   }                                                                                                                     
│   │   console.log('a1:',JSON.parse(localStorage.todos))                                                                     
│   }, [])                                                                                                                    
│   useEffect(() => {                                                                                                         
│   │   // if (todos.length > 0) {                                                                                            
│   │   │   console.log('b2:',JSON.parse(localStorage.todos))                                                                 
│   │   │   localStorage.setItem("todos", JSON.stringify(todos))                                                              
│   │   │   console.log('a2:',JSON.parse(localStorage.todos))                                                                 
│   │   // }                                                                                                                  
│   }, [todos])     

控制台输出(b1 before1, a1 after1等):

[Log] b1: – [{text: "one", done: false, id: "6c570584b1a"}] (1)
[Log] [{text: "one", done: false, id: "6c570584b1a"}] (1)
[Log] a1: – [{text: "one", done: false, id: "6c570584b1a"}] (1)
[Log] b2: – [{text: "one", done: false, id: "6c570584b1a"}] (1)
[Log] a2: – [] (0)
[Log] b1: – [] (0)
[Log] [] (0)
[Log] a1: – [] (0)
[Log] b2: – [] (0)
[Log] a2: – [] (0)
[Log] b2: – [] (0)
[Log] a2: – [] (0)

useState钩子是异步的。根据你的代码,你在第一个useEffect中调用setTodos,然后在第二个useEffect中调用todos状态,不确定todos状态是否更新。

useEffect也将在组件渲染后第一次触发,即使它有依赖项(在你的情况下,它是[todos])。

对于一个可能的修复,您应该添加一个条件来检查todos状态,然后在第二个useEffect中再次更新它。

useEffect(() => {                                                                                                         
console.log('b1:',JSON.parse(localStorage.todos))                                                                     
if (localStorage.todos !==null) {                                                                                     
console.log(JSON.parse(localStorage.todos))                                                                       
setTodos(JSON.parse(localStorage.todos))                                                                          
}                                                                                                                     
console.log('a1:',JSON.parse(localStorage.todos))                                                                     
}, [])                                                                                                                    
useEffect(() => {                                                                                                         
if (todos && todos.length > 0) {                                                                                            
console.log('b2:',JSON.parse(localStorage.todos))                                                                 
localStorage.setItem("todos", JSON.stringify(todos))                                                              
console.log('a2:',JSON.parse(localStorage.todos))                                                                 
}                                                                                                                  
}, [todos])  

您实现的那些副作用不适合delete-all情况。所以我想提出两个解决方案

第一个解决方案是使用另一个状态来跟踪第一次加载和下一次加载(如调用api)

const [isLoaded, setIsLoaded] = useState(false)
useEffect(() => {                                                                                                         
console.log('b1:',JSON.parse(localStorage.todos))                                                                     
if (localStorage.todos !==null) {                                                                                     
console.log(JSON.parse(localStorage.todos))                                                                       
setTodos(JSON.parse(localStorage.todos)) 
setIsLoaded(true)                                                                         
}                                                                                                                     
console.log('a1:',JSON.parse(localStorage.todos))                                                                     
}, [])                                                                                                                    
useEffect(() => {                                                                                                             
if(isLoaded) {
console.log('b2:',JSON.parse(localStorage.todos))                                                                 
localStorage.setItem("todos", JSON.stringify(todos))                                                              
console.log('a2:',JSON.parse(localStorage.todos)) 
}                                                                                             
}, [todos, isLoaded])  

第二个解决方案是在deleteAll中更新localStorage而不是

useEffect(() => {                                                                                                         
console.log('b1:',JSON.parse(localStorage.todos))                                                                     
if (localStorage.todos !==null) {                                                                                     
console.log(JSON.parse(localStorage.todos))                                                                       
setTodos(JSON.parse(localStorage.todos))                                                                          
}                                                                                                                     
console.log('a1:',JSON.parse(localStorage.todos))                                                                     
}, [])                                                                                                                    
useEffect(() => {                                                                                                         
if (todos && todos.length > 0) {                                                                                            
console.log('b2:',JSON.parse(localStorage.todos))                                                                 
localStorage.setItem("todos", JSON.stringify(todos))                                                              
console.log('a2:',JSON.parse(localStorage.todos))                                                                 
}                                                                                                                  
}, [todos])  
function deleteAll() {
setTodos(null)
localStorage.removeItem("todos")  
}

最新更新