-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: persisted storage #531
Open
FoundTheWOUT
wants to merge
3
commits into
bangumi:master
Choose a base branch
from
FoundTheWOUT:persisted-storage
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+71
−8
Open
Changes from 2 commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { useEffect, useRef } from 'react'; | ||
|
||
type Getter<T> = () => T; | ||
interface Options<T> { | ||
getter: Getter<T>; | ||
} | ||
type PersistedStorage = <T>( | ||
id: string, | ||
options?: Options<T>, | ||
) => { | ||
/** | ||
* 从 storage 中获取的数据,没有则返回 null | ||
*/ | ||
data: T | null; | ||
/** | ||
* 存储数据时,将会调用该函数获取存储的数据 | ||
* | ||
* 为什么需要这个? | ||
* 在一些场景,我们需要该 hook 提供的初始数据,来初始化其它 hook | ||
* 而 getter 又依赖那些 hook。见 edit_detail 页面 | ||
*/ | ||
setGetter: (getter: Getter<T>) => void; | ||
/** | ||
* 调用后,代表数据将不会被保存 | ||
*/ | ||
finish: () => void; | ||
}; | ||
export const usePersistedStorage: PersistedStorage = <T>(id: string, options?: Options<T>) => { | ||
const _id = `resume:${id}`; | ||
const item = sessionStorage.getItem(_id); | ||
if (item) { | ||
sessionStorage.removeItem(_id); | ||
} | ||
const getterRef = useRef<null | Getter<T>>(options?.getter ?? null); | ||
const finished = useRef(false); | ||
|
||
const setGetter = (getter: Getter<T>) => { | ||
getterRef.current = getter; | ||
}; | ||
|
||
useEffect(() => { | ||
return () => { | ||
// 组件 unmount 时存储 | ||
if (!finished.current) { | ||
getterRef.current && sessionStorage.setItem(_id, JSON.stringify(getterRef.current())); | ||
} | ||
}; | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, []); | ||
return { | ||
data: item ? (JSON.parse(item) as T) : null, | ||
setGetter, | ||
finish: () => { | ||
finished.current = true; | ||
}, | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
页面崩了咋办,数据丢了?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
页面崩掉要分几种情况吧。
如果是 throw Error 那种不会导致整个组件崩掉,状态还是会在的,而且如果是这种错误应该我们这边处理一下(比如解析 wiki 错误加个弹窗之类的)
如果是整个页面崩了,就是状态都没了的话是什么情况呢,不太清楚怎么触发这类错误🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
比如浏览器某个页面卡死了,用户只能用任务管理器强制 kill 掉浏览器?总之是那种非正常的退出?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这种存储策略,非正常退出应该没办法~就是正常退出,比如用户直接叉掉页面也是没办法(
针对这种的话可能用实时缓存好点?然后加个 throttle 之类的。