从reducer钩子保存到localStorage

时间:2019-01-24 12:37:11

标签: reactjs

我正在使用useReducer钩子来保存一些全局状态。因为我想在关闭浏览器时保存一些设置,所以将这些设置保存到本地存储中。

目前,我使用分派来保存设置,并使用单独的功能将其保存到本地存储中,但是如果在分派后自动保存设置,那就很好了。 (有时我会忘记保存到本地存储,而状态/本地存储之间会有区别)

从本地存储读取状态不是问题。为此,我在useReducer挂钩中使用了initialState参数。

我认为答案是不这样做,但是替代品是什么? (不使用redux)

3 个答案:

答案 0 :(得分:1)

我认为让服务负责将数据存储到localStorage以及将其存储到localStorage是明智的。因此,您可能想使用get和set函数创建服务。您可以从redux中的效果调用服务。

我认为,减速器在那里可以改变状态。

您还可以使用rxjs等待reducer更新您的状态,然后使用您的服务获取该状态并将其保存到localStorage。

顺便说一句,根据您的需要,我没有发现没有任何理由不应该将数据存储在localStorage中,只要您记住(使用redux时)记住redux状态是您唯一的真理。以我最诚实的看法,将数据存储在某个位置以在初始化时恢复该状态是一个好方法。

以下是使用ngrx的示例:

@Effect()
myAction$: Observable<Action> = this.actions$.pipe(
  ofType<MyAction>(actions.myAction),
  debounceTime(300),
  switchMap((action) =>
    this.service.post(action.dto).pipe(
      map((response: SomeDto) => {
        // This updates the state using a reducer
        return new CreateShortenedLinkSuccess(response);
      }),
      tap((value) => {
        // Here, you can use the value param, to save
        // changes to localStorage
        this.router.navigate([`/mgmt/link/${value.dto.id}`]);
      }),
      catchError((response: HttpErrorResponse) => {
        // Do scary stuff
      })
    )
  )
);

答案 1 :(得分:1)

我发现@Zaid Crouch很棒,但是它不能处理来自不同窗口(选项卡/ iframe /弹出窗口)的本地存储更新。

REPLACE

答案 2 :(得分:0)

我只是在做类似的事情,并且想尝试使用可以代替useReducer的自定义钩子来实现它。出现了以下粗略的钩子(我确实添加了一个额外的参数,以便可以指定数据存储在其下的键):

import { useRef, useReducer } from 'react'

function useLocallyPersistedReducer(reducer, defaultState, storageKey) {
  const isLoading = useRef(true)
  if (isLoading.current) {
    try {
      const persisted = JSON.parse(localStorage.getItem(storageKey))
      defaultState = persisted
    } catch (e) {
      console.warn(`Failed to load state '${storageKey}' from localStorage; using default state instead`)
    }
    isLoading.current = false
  }

  const [ state, dispatch ] = useReducer(reducer, defaultState)

  try {
    localStorage.setItem(storageKey, JSON.stringify(state))
  } catch (e) {
    console.warn(`Failed to store updated state '${storageKey}'`)
  }

  return [ state, dispatch ]
}

作为一项艰巨的工作,它可以工作,但是我可能错过了一些细微差别。希望能使您对如何实现这一想法有所了解!