最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to make useEffect listening to any change in localStorage? - Stack Overflow

programmeradmin1浏览0评论

I am trying to have my React app getting the todos array of objects from the localStorage and give it to setTodos. To do that I need to have a useEffect that listen to any change that occurs in the local storage so this is what I did:

  useEffect(() => {
      if(localStorage.getItem('todos')) {
        const todos = JSON.parse(localStorage.getItem('todos'))
        setTodos(todos);
      }
  }, [ window.addEventListener('storage', () => {})]);

The problem is that useEffect is not triggered each time I add or remove something from the localStorage. Is this the wrong way to have useEffect listening to the localStorage?

I tried the solution explained here but it doesn't work for me and I sincerely I do not understand why it should work because the listener is not passed as a second parameter inside the useEffect

I am trying to have my React app getting the todos array of objects from the localStorage and give it to setTodos. To do that I need to have a useEffect that listen to any change that occurs in the local storage so this is what I did:

  useEffect(() => {
      if(localStorage.getItem('todos')) {
        const todos = JSON.parse(localStorage.getItem('todos'))
        setTodos(todos);
      }
  }, [ window.addEventListener('storage', () => {})]);

The problem is that useEffect is not triggered each time I add or remove something from the localStorage. Is this the wrong way to have useEffect listening to the localStorage?

I tried the solution explained here but it doesn't work for me and I sincerely I do not understand why it should work because the listener is not passed as a second parameter inside the useEffect

Share Improve this question asked May 25, 2021 at 7:37 Andrea D_Andrea D_ 2,1415 gold badges21 silver badges45 bronze badges 2
  • Are you just wanting to initialize state from localStorage persist state updates to localStorage? Or do you actually need to watch local storage for changes made from elsewhere? – Drew Reese Commented May 25, 2021 at 7:41
  • I am curious why do you need this? To the best of my knowledge, localStorage is not designed to be used as a state for your application ( you can only store strings in it). There are other ways to do it (react's context API, react-redux). Sure, if you want some data to persist, you can sync your context / redux with your localStorage, but you won't need that for most of the use cases. Also, keep in mind that localStorage has a maximum capacity (5 MB per app per browser). – Ionut Bîrsu Commented May 25, 2021 at 7:53
Add a comment  | 

2 Answers 2

Reset to default 13

You can't re-run the useEffect callback that way, but you can set up an event handler and have it re-load the todos, see comments:

useEffect(() => {
    // Load the todos on mount
    const todosString = localStorage.getItem("todos");
    if (todosString) {
        const todos = JSON.parse(todosString);
        setTodos(todos);
    }
    // Respond to the `storage` event
    function storageEventHandler(event) {
        if (event.key === "todos") {
            const todos = JSON.parse(event.newValue);
            setTodos(todos);
        }
    }
    // Hook up the event handler
    window.addEventListener("storage", storageEventHandler);
    return () => {
        // Remove the handler when the component unmounts
        window.removeEventListener("storage", storageEventHandler);
    };
}, []);

Beware that the storage event only occurs when the storage is changed by code in a different window to the current one. If you change the todos in the same window, you have to trigger this manually.

const [todos, setTodos] = useState();

useEffect(() => {
  setCollapsed(JSON.parse(localStorage.getItem('todos')));
}, [localStorage.getItem('todos')]);
发布评论

评论列表(0)

  1. 暂无评论