diff --git a/package.json b/package.json index 7cc1d73..94cc57a 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "remark-rehype": "^11.1.0", "swr": "^2.2.4", "unified": "^11.0.4", + "use-resize-observer": "^9.1.0", "zustand": "^4.5.0" }, "devDependencies": { diff --git a/src/components/AppList.tsx b/src/components/AppList.tsx index bb44839..9b5f520 100644 --- a/src/components/AppList.tsx +++ b/src/components/AppList.tsx @@ -1,9 +1,10 @@ import { css } from "@emotion/react"; import { AppItem } from "../api/banglejs/interface"; import { AppListItem } from "./AppListItem"; -import { CSSProperties, HTMLAttributes, useLayoutEffect, useRef, useState } from "react"; +import { CSSProperties, HTMLAttributes, useMemo } from "react"; import { Link } from "react-router-dom"; import { ListRowRenderer, List } from 'react-virtualized/dist/es/List'; +import useResizeObserver from "use-resize-observer"; export interface AppListProps { isLoading: boolean; @@ -13,49 +14,53 @@ export interface AppListProps { style?: CSSProperties; } -const getDimension = (element: HTMLElement) => { - return { - height: element.parentElement!.clientHeight, - width: element.parentElement!.clientWidth, - } -}; +interface Dimension { + width: number; + height: number; +} export const AppList = ({ isLoading, error, data: apps, ...props }: AppListProps) => { - const [ dimension, setDimension ] = useState({ width: 0, height: 0 }); - const ref = useRef(null); - - useLayoutEffect(() => { - const element = ref.current; - const resizeHandler = () => { - if (element) { - setDimension(getDimension(element)) - } - }; + const { ref, width = 0, height = 0 } = useResizeObserver(); - const observer = new ResizeObserver(() => { - resizeHandler() - }); - resizeHandler(); - - if (element) observer.observe(element); + return ( +
+ { + (() => { + if (isLoading) { + return Fetching store... + } + if (error) { + return Error fetching store, please try again later... + } - return () => { - if (element) { - observer.unobserve(element); - observer.disconnect(); + return ( + + ) + })() } - } - }, []) - +
+ ) +}; - if (isLoading) { - return Fetching store... - } - if (error) { - return Error fetching store, please try again later... - } +interface AppListWaProps { + apps: AppItem[]; + dimension: Dimension; +} - const RowRenderer: ListRowRenderer = (p) => { +const AppListListView = ({ apps, dimension, ...props }: AppListWaProps) => { + const RowRenderer = useMemo((): ListRowRenderer => (p) => { const app = apps[p.index]; return ( @@ -76,25 +81,18 @@ export const AppList = ({ isLoading, error, data: apps, ...props }: AppListProps /> ); - } + }, [apps]) return ( -
- -
+ ) }; diff --git a/yarn.lock b/yarn.lock index 5ecd931..43c2fba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -539,6 +539,11 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@juggle/resize-observer@^3.3.1": + version "3.4.0" + resolved "https://registry.yarnpkg.com/@juggle/resize-observer/-/resize-observer-3.4.0.tgz#08d6c5e20cf7e4cc02fd181c4b0c225cd31dbb60" + integrity sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -3167,6 +3172,13 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" +use-resize-observer@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/use-resize-observer/-/use-resize-observer-9.1.0.tgz#14735235cf3268569c1ea468f8a90c5789fc5c6c" + integrity sha512-R25VqO9Wb3asSD4eqtcxk8sJalvIOYBqS8MNZlpDSQ4l4xMQxC/J7Id9HoTqPq8FwULIn0PVW+OAqF2dyYbjow== + dependencies: + "@juggle/resize-observer" "^3.3.1" + use-sync-external-store@1.2.0, use-sync-external-store@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"