Как мгновенно обновлять состояние при любых изменениях в localStorage в React. js - PullRequest
0 голосов
/ 14 июля 2020

Как мгновенно обновить данные страницы корзины при любых изменениях в массиве localStorage myCart? Вот мой код ниже

const [cart, setCart] = React.useState([])

React.useEffect(() => {
    setCart(JSON.parse(localStorage.getItem('myCart')) || [])
}, [])

cart обновляется при перезагрузке страницы, но не когда новый элемент добавляет или обновляет какие-либо существующие элементы!

Как я могу этого добиться, а именно cart обновлять мгновенно, если какие-либо изменения в localStorage?

Заранее спасибо.

Ответы [ 2 ]

3 голосов
/ 14 июля 2020

Вы можете добавить прослушиватель событий к localstorage событию

React.useEffect(() => {
    
window.addEventListener('storage', () => {
  // When local storage changes, dump the list to
  // the console.
   setCart(JSON.parse(localStorage.getItem('myCart')) || [])   
});

   
}, [])

Событие хранилища интерфейса Window срабатывает, когда область хранилища (localStorage) была изменена .Событие хранилища запускается, только когда окно, отличное от него, вносит изменения.

.

0 голосов
/ 14 июля 2020

Я думаю, что это лучший способ справиться с ситуацией. Вот как я справляюсь с такой ситуацией.

В вашем компоненте,

const [cart, setCart] = useState([]);

React.useEffect(() => {
    async function init() {
      const data = await localStorage.getItem('myCart'); 
      setCart(JSON.parse(data));
    }
    init();
}, [])

корзина обновляется при перезагрузке страницы, но не когда новый элемент добавляет или обновляет существующие items!

Как я могу этого добиться, то есть мгновенное обновление корзины, если какие-либо изменения в localStorage?

Когда вы добавляете элементы, предположим, что у вас есть метод addItem()

async function addItem(item) {
  // Do not update local-storage, instead update state
  await setState(cart => cart.push(item));
}

Теперь добавьте еще useEffect();

useEffect(() => {
 localstorage.setItem('myCart', cart);
}, [cart])

Теперь, когда изменение состояния корзины будет сохранено в локальном хранилище

addEventListener на хранилище не является хорошая вещь. Каждый раз при изменении хранилища в вашем коде вы должны получить элементы и проанализировать его, что занимает несколько миллисекунд, что приводит к замедлению обновления пользовательского интерфейса.

В реакции

  1. сначала загрузить данные из localstorage / database и инициализировать состояние.
  2. Затем обновить состояние в коде по своему усмотрению.
  3. Затем прослушать изменения состояния, чтобы выполнить любую задачу (в этом case save to localstorage)

Если ваша функция addItem() является дочерней по отношению к указанному выше компоненту (компонент корзины), то вы можете передать функцию setItem как опору / или вы можете использовать контекст API или используйте Redux

UPDATE

Если addCart - другой компонент

  1. , если компонент, имеющий функцию addCart, является дочерним компонентом cart компонент, используйте props - https://reactjs.org/docs/components-and-props.html
  2. , если компонент, имеющий функцию addCart, НЕ является дочерним компонентом компонента cart, используйте context api для связи между компонентами - https://reactjs.org/docs/context.html
  3. если вы хотите м обработайте ваши данные более чистым и лучшим способом, используйте https://redux.js.org/

В соответствии с вариантом использования, я предполагаю, что ваша функция addItem объявлена ​​в компоненте Product ..

Я рекомендую вам использовать Redux для обработки ситуации.

ОБНОВЛЕНИЕ

Как сказал @Matt Morgan в разделе комментариев, использование контекстного API лучше для ситуации.

Но если ваше приложение большое (я предполагал, что вы создаете систему электронной коммерции), возможно, лучше использовать систему управления состоянием, такую ​​как Redux. Как раз на этот случай хватит контекстного API

...