【问题标题】:useEffect dosn't save data in localstorageuseEffect 不会将数据保存在本地存储中
【发布时间】:2021-10-14 21:18:23
【问题描述】:

我有一个简单的应用程序,用于聊天目的。我从 json 格式的静态文件中获取数据。所以这个应用程序显示了该文件中的所有消息,但我还想编辑这些消息,删除它们并通过本地存储添加。为此我使用了useEffect,但刷新后我所做的所有更改都消失了。

这是我的组件:

export const WorkChat = (props) => {
    const [messageValue, setMessageValue] = useState('');
    const [edit, setEdit] = useState(null);
    const [editmessageValue, setMessageEditValue] = useState('')

    const submitMessage = () => {
        const newMessage = {
            id: Math.floor(Math.random() * 10000),
            message: messageValue
        }
        props.addMessage(newMessage);
        setMessageValue('')
    }

    const removeMsg = (id) => {
        props.deleteMessage(id)
    }

    const goToEditMode = (message) => {
        setEdit(message.id);
        setMessageEditValue(message.message)
    }

    const saveChanges = (id) => {
        const newMessagesArray = props.messages.map(m => {
            if(m.id === id){
                m.message = editmessageValue
            }
            return m
        })
        props.updateMessage(newMessagesArray);
        setEdit(null)
    }

    
    useEffect(()=> {
        let data = localStorage.getItem('work-messages');
        if(data){
          props.setMessages(JSON.parse(data))
        }
      }, []);

      
    useEffect(()=> {
        localStorage.setItem('work-messages', JSON.stringify(props.messages))
    },[props.messages])


    return (
        <div className={s.workChatContainer}>
           <input className={s.workInput} placeholder='Enter work message...' onChange={(e)=> setMessageValue(e.target.value)} value={messageValue}/>
           <button className={`${s.btn} ${s.sendBtn}`} onClick={()=>submitMessage()}><SendIcon style={{fontSize: 20}}/></button>
           <div>
                {props.messages.map(m => (
                    <div key={m.id} className={s.messages}>
                        {edit !== m.id ? <div>
                            <span className={s.message}>{m.message}</span>
                            <button className={`${s.btn} ${s.deleteBtn}`} onClick={()=> removeMsg(m.id)}><DeleteOutlineIcon style={{fontSize: 15}}/></button>
                            <button className={`${s.btn} ${s.editBtn}`} onClick={()=> goToEditMode(m)}><EditIcon style={{fontSize: 15}}/></button>
                        </div>
                        :
                        <form>
                            <input className={s.editInput} value={editmessageValue} onChange={(e)=> setMessageEditValue(e.target.value)}/>
                            <button className={`${s.btn} ${s.saveBtn}`} onClick={()=> saveChanges(m.id)}><BeenhereIcon style={{fontSize: 15}}/></button>
                        </form>
                    }
                        
               </div>
                ))} 
           </div>
        </div>
    )
}

以防万一,这是我的容器组件:

import { connect } from "react-redux"
import { setFloodMessagesAC, addFloodMessageAC, deleteFloodMessageAC, upadateMessageAC } from "../../redux/flood-reducer"
import { FloodChat } from "./FloodChat"
import { useEffect } from 'react'
import  data  from '../../StaticState/dataForFlood.json'


const FloodChatApiContainer = (props) => {

    useEffect(()=> {
        props.setFloodMessages(data)
    }, [])
    
    
    return <FloodChat messages={props.messages}
                      setFloodMessages={props.setFloodMessages}
                      addFloodMessage={props.addFloodMessage}
                      deleteFloodMessage={props.deleteFloodMessage}
                      upadateMessage={props.upadateMessage}
                                                    />
}

const mapStateToProps = (state) => ({
    messages: state.flood.messages
})

export const FloodChatContainer = connect(mapStateToProps, {
    setFloodMessages: setFloodMessagesAC,
    addFloodMessage: addFloodMessageAC,
    deleteFloodMessage: deleteFloodMessageAC,
    upadateMessage: upadateMessageAC
})(FloodChatApiContainer)

为什么 useEffect 不起作用?在我看来是应该的,但事实并非如此。

【问题讨论】:

  • props.messages 更改时是否触发了第二个useEffect()
  • @Ryan Le 是的,它被触发了,刚刚通过console.log检查了它,它在我更改smth时触发(删除,添加或编辑)

标签: reactjs local-storage use-effect


【解决方案1】:

我想通了。由于我使用来自静态文件的数据,我需要实现从本地存储获取/设置数据的功能,就在我导入它的地方,这是容器组件。一旦我将这些 useEffect 函数放入容器组件中,它就可以很好地工作。

const FloodChatApiContainer = (props) => {

    useEffect(()=> {
        props.setFloodMessages(data)
    }, [])
            
    useEffect(()=> {
        let data = JSON.parse(localStorage.getItem('flood-messages'));
        if(data){
            props.setFloodMessages(data)
        }
        console.log('get')
    }, [])

    useEffect(() => {
        localStorage.setItem('flood-messages', JSON.stringify(props.messages));
        console.log('set')
      }, [props.messages]);

    
    
    return <FloodChat messages={props.messages}
                      setFloodMessages={props.setFloodMessages}
                      addFloodMessage={props.addFloodMessage}
                      deleteFloodMessage={props.deleteFloodMessage}
                      upadateMessage={props.upadateMessage}
                                                    />
}

const mapStateToProps = (state) => ({
    messages: state.flood.messages
})

export const FloodChatContainer = connect(mapStateToProps, {
    setFloodMessages: setFloodMessagesAC,
    addFloodMessage: addFloodMessageAC,
    deleteFloodMessage: deleteFloodMessageAC,
    upadateMessage: upadateMessageAC
})(FloodChatApiContainer)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多