fix: to fix the mistakes I have made about react (#791)

This commit is contained in:
Innei 2023-07-18 22:20:18 +08:00 committed by GitHub
parent 86e1747979
commit 2fbf21d60c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 62 additions and 27 deletions

View File

@ -7,7 +7,6 @@ import {
COLOR_SCHEME_LIGHT,
DARK_MODE_STORAGE_KEY,
} from "~/lib/constants"
import { getStorage } from "~/lib/storage"
export const ColorSchemeInjector = () => {
useServerInsertedHTML(() => {
@ -16,7 +15,14 @@ export const ColorSchemeInjector = () => {
dangerouslySetInnerHTML={{
__html: `(() => {
var DARK_MODE_STORAGE_KEY = "${DARK_MODE_STORAGE_KEY}";
var getStorage = ${getStorage.toString()};
var namespace = "xlog"
var getStorage = () => {
const data = {}
try {
data = JSON.parse(localStorage.getItem(namespace) || "{}")
} catch (error) {}
return data
}
var COLOR_SCHEME_LIGHT = "${COLOR_SCHEME_LIGHT}";
var COLOR_SCHEME_DARK = "${COLOR_SCHEME_DARK}";

View File

@ -34,6 +34,7 @@ const colorScheme: NotificationModalColorScheme = {
border: `var(--border-color)`,
}
const createQueryClient = () => new QueryClient()
export default function Providers({
children,
lang,
@ -45,7 +46,7 @@ export default function Providers({
useMobileLayout()
useNProgress()
const [queryClient] = useState(() => new QueryClient())
const [queryClient] = useState(createQueryClient)
return (
<WagmiConfig config={wagmiConfig}>

15
src/hooks/useRefValue.ts Normal file
View File

@ -0,0 +1,15 @@
import { useRef } from "react"
// @see https://react.dev/reference/react/useRef#avoiding-recreating-the-ref-contents
export const useRefValue = <T>(value: () => T): T => {
const ref = useRef<T>()
const onceRef = useRef(false)
if (!onceRef.current) {
ref.current = value()
onceRef.current = true
}
return ref.current!
}

View File

@ -1,19 +1,51 @@
import { usePathname, useRouter, useSearchParams } from "next/navigation"
import { useEffect, useRef, useState } from "react"
import { useEffect, useState } from "react"
import { pick } from "~/lib/utils"
import { useRefValue } from "./useRefValue"
interface RouterNavigationEvent {}
type RouterEventFunction = (e: RouterNavigationEvent) => void
const createRegister = () => {
const props = {
onStartQ: [] as RouterEventFunction[],
// onErrorQ: [] as RouterEventFunction[],
onCompleteQ: [] as RouterEventFunction[],
} as {
onStartQ: RouterEventFunction[]
// onErrorQ: RouterEventFunction[]
onCompleteQ: RouterEventFunction[]
onStart: (cb: RouterEventFunction) => () => void
// onError: (cb: RouterEventFunction) => () => void
onComplete: (cb: RouterEventFunction) => () => void
}
props.onStart = (cb: RouterEventFunction) => {
props.onStartQ.push(cb)
return () => {
props.onStartQ = props.onStartQ.filter(($) => $ !== cb)
}
}
props.onComplete = (cb: RouterEventFunction) => {
props.onCompleteQ.push(cb)
return () => {
props.onCompleteQ = props.onCompleteQ.filter(($) => $ !== cb)
}
}
return props
}
// TODO detect error event
export const useAppRouterEventerListener = () => {
const [isRouterComplete, setIsRouterComplete] = useState(false)
const startChangeCallback = () => {
setIsRouterComplete(false)
eventsRegisters.current.onStartQ.forEach(($) => $(buildEvent()))
eventsRegisters.onStartQ.forEach(($) => $(buildEvent()))
}
const router = useRouter()
useEffect(() => {
@ -48,26 +80,7 @@ export const useAppRouterEventerListener = () => {
}
}, [])
const eventsRegisters = useRef({
onStartQ: [] as RouterEventFunction[],
// onErrorQ: [] as RouterEventFunction[],
onCompleteQ: [] as RouterEventFunction[],
onStart(cb: RouterEventFunction) {
eventsRegisters.current.onStartQ.push(cb)
return () => {
eventsRegisters.current.onStartQ =
eventsRegisters.current.onStartQ.filter(($) => $ !== cb)
}
},
onComplete(cb: RouterEventFunction) {
eventsRegisters.current.onCompleteQ.push(cb)
return () => {
eventsRegisters.current.onCompleteQ =
eventsRegisters.current.onCompleteQ.filter(($) => $ !== cb)
}
},
})
const eventsRegisters = useRefValue(createRegister)
const buildEvent = (): RouterNavigationEvent => {
return {
@ -78,7 +91,7 @@ export const useAppRouterEventerListener = () => {
useEffect(() => {
if (!isRouterComplete) return
eventsRegisters.current.onCompleteQ.forEach(($) => $(buildEvent()))
eventsRegisters.onCompleteQ.forEach(($) => $(buildEvent()))
}, [isRouterComplete])
const currentPathname = usePathname()
@ -94,5 +107,5 @@ export const useAppRouterEventerListener = () => {
}
}, [currentPathname, searchParams])
return pick(eventsRegisters.current, ["onStart", "onComplete"])
return pick(eventsRegisters, ["onStart", "onComplete"])
}