Mar*_*rco 3 typescript reactjs react-hooks
当页面呈现时,挂钩会检查存储中是否存在持久的模拟信息,如果有,则在全局 AppState 上下文中设置这些信息。
const impersonateStorageKey = `impersonation_${config.environment}`
// signature const impersonate: (empScope: number) => void
const { currentImpersonation, impersonate } = useAppContext()
useEffect(() => {
if (!window || !window.localStorage) return;
const storageString = localStorage.getItem(impersonateStorageKey)
if (!storageString) return;
const data = JSON.parse(storageString)
impersonate(data.currentImpersonation)
}, [impersonateStorageKey])
Run Code Online (Sandbox Code Playgroud)
使用第二个钩子,将当前模拟身份的更改持久保存到存储中:
useEffect(() => {
if (!window || !window.localStorage) return;
localStorage.setItem(impersonateStorageKey, JSON.stringify({ /* ... */}))
}, [currentImpersonation, impersonateStorageKey])
Run Code Online (Sandbox Code Playgroud)
加上相关位useAppContext
const useAppContext = () => {
const { state, dispatch } = useContext(AppContext)
if (!state) {
throw new Error("useAppContext must be used within within AppContextProvider")
}
const impersonate = (employeeScope: string | number) => dispatch({ type: 'IMPERSONATE', value: employeeScope })
const currentImpersonation = state.currentImpersonation
return {
impersonate,
currentImpersonation,
}
}
Run Code Online (Sandbox Code Playgroud)
这是正常工作的,但是 linter 抱怨第一个 useEffect 钩子中缺少依赖模拟
当我添加impersonate到依赖项数组时,这将导致不断的更新循环并使应用程序无响应。
我知道是什么导致了这种行为,但我没有找到关于如何打破循环并使linter 满意的解决方案(除了忽略规则)。
我在这里可以采取什么方法?
您可以在创建函数时使用以下命令记住该函数useCallback:
const useAppContext = () => {
const { state, dispatch } = useContext(AppContext)
const impersonate = useCallback(
(employeeScope: string | number) => dispatch({
type: 'IMPERSONATE',
value: employeeScope
}), [dispatch])
if (!state) {
throw new Error("useAppContext must be used within within AppContextProvider")
}
const currentImpersonation = state.currentImpersonation
return {
impersonate,
currentImpersonation,
}
}
Run Code Online (Sandbox Code Playgroud)
如果不能,解决方法是将函数放入ref中。是ref对对象的不可变引用,其current属性是可变的。由于它ref本身是不可变的,因此您可以将其用作依赖项,而不会导致useEffect激活(linter 知道它,您甚至不需要将其声明为依赖项)。你可以current随心所欲地变异。
const impersonateRef = useRef(impersonate)
useEffect(() => {
impersonateRef.current = impersonate
}, [impersonate])
useEffect(() => {
if (!window || !window.localStorage) return
const storageString = localStorage.getItem(impersonateStorageKey)
if (!storageString) return
const data = JSON.parse(storageString)
impersonateRef.current(data.currentImpersonation)
}, [impersonateStorageKey])
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
131 次 |
| 最近记录: |