2/n reduce react re-renders

This commit is contained in:
Igor Katson 2023-12-19 23:05:57 +00:00
parent e6ef3ff23f
commit 89bbcd2a27
No known key found for this signature in database
GPG key ID: B4EC22B66D61A3F5
7 changed files with 66 additions and 25 deletions

File diff suppressed because one or more lines are too long

View file

@ -11,7 +11,7 @@
"css": [ "css": [
"assets/index-d46108e9.css" "assets/index-d46108e9.css"
], ],
"file": "assets/index-3e8911ff.js", "file": "assets/index-e6c23bc1.js",
"isEntry": true, "isEntry": true,
"src": "index.html" "src": "index.html"
} }

View file

@ -8,7 +8,9 @@ export const RootContent = (props: {}) => {
let setCloseableError = useErrorStore((state) => state.setCloseableError); let setCloseableError = useErrorStore((state) => state.setCloseableError);
let otherError = useErrorStore((state) => state.otherError); let otherError = useErrorStore((state) => state.otherError);
let torrents = useTorrentStore((state) => state.torrents); let torrents = useTorrentStore((state) => state.torrents);
let torrentsLoading = useTorrentStore((state) => state.torrentsLoading); let torrentsInitiallyLoading = useTorrentStore(
(state) => state.torrentsInitiallyLoading
);
return ( return (
<div className="container mx-auto"> <div className="container mx-auto">
@ -17,7 +19,7 @@ export const RootContent = (props: {}) => {
remove={() => setCloseableError(null)} remove={() => setCloseableError(null)}
/> />
<ErrorComponent error={otherError} /> <ErrorComponent error={otherError} />
<TorrentsList torrents={torrents} loading={torrentsLoading} /> <TorrentsList torrents={torrents} loading={torrentsInitiallyLoading} />
</div> </div>
); );
}; };

View file

@ -1,15 +1,13 @@
import { useCallback, useContext, useEffect, useState } from "react"; import { useContext, useEffect, useState } from "react";
import { AddTorrentResponse, AddTorrentOptions } from "../../api-types"; import { AddTorrentResponse, AddTorrentOptions } from "../../api-types";
import { APIContext } from "../../context"; import { APIContext } from "../../context";
import { ErrorComponent } from "../ErrorComponent"; import { ErrorComponent } from "../ErrorComponent";
import { formatBytes } from "../../helper/formatBytes";
import { ErrorWithLabel } from "../../rqbit-web"; import { ErrorWithLabel } from "../../rqbit-web";
import { Spinner } from "../Spinner"; import { Spinner } from "../Spinner";
import { Modal } from "./Modal"; import { Modal } from "./Modal";
import { ModalBody } from "./ModalBody"; import { ModalBody } from "./ModalBody";
import { ModalFooter } from "./ModalFooter"; import { ModalFooter } from "./ModalFooter";
import { Button } from "../buttons/Button"; import { Button } from "../buttons/Button";
import { FormCheckbox } from "../forms/FormCheckbox";
import { Fieldset } from "../forms/Fieldset"; import { Fieldset } from "../forms/Fieldset";
import { FormInput } from "../forms/FormInput"; import { FormInput } from "../forms/FormInput";
import { Form } from "../forms/Form"; import { Form } from "../forms/Form";
@ -40,7 +38,6 @@ export const FileSelectionModal = (props: {
const API = useContext(APIContext); const API = useContext(APIContext);
useEffect(() => { useEffect(() => {
console.log(listTorrentResponse);
setSelectedFiles( setSelectedFiles(
new Set(listTorrentResponse?.details.files.map((_, i) => i)) new Set(listTorrentResponse?.details.files.map((_, i) => i))
); );

View file

@ -25,14 +25,14 @@ const RootWithVersion = () => {
}, []); }, []);
return ( return (
<StrictMode> <APIContext.Provider value={API}>
<APIContext.Provider value={API}> <RqbitWebUI title={title} />
<RqbitWebUI title={title} /> </APIContext.Provider>
</APIContext.Provider>
</StrictMode>
); );
}; };
ReactDOM.createRoot(document.getElementById("app") as HTMLInputElement).render( ReactDOM.createRoot(document.getElementById("app") as HTMLInputElement).render(
<RootWithVersion /> <StrictMode>
<RootWithVersion />
</StrictMode>
); );

View file

@ -5,6 +5,7 @@ export interface TorrentStore {
torrents: Array<TorrentId> | null; torrents: Array<TorrentId> | null;
setTorrents: (torrents: Array<TorrentId>) => void; setTorrents: (torrents: Array<TorrentId>) => void;
torrentsInitiallyLoading: boolean;
torrentsLoading: boolean; torrentsLoading: boolean;
setTorrentsLoading: (loading: boolean) => void; setTorrentsLoading: (loading: boolean) => void;
@ -12,11 +13,42 @@ export interface TorrentStore {
setRefreshTorrents: (callback: () => void) => void; setRefreshTorrents: (callback: () => void) => void;
} }
const torrentIdEquals = (t1: TorrentId, t2: TorrentId): boolean => {
return t1.id == t2.id && t1.info_hash == t2.info_hash;
};
const torrentsEquals = (t1: TorrentId[] | null, t2: TorrentId[] | null) => {
if (t1 === null && t2 === null) {
return true;
}
if (t1 === null || t2 === null) {
return false;
}
return (
t1.length === t2.length && t1.every((t, i) => torrentIdEquals(t, t2[i]))
);
};
export const useTorrentStore = create<TorrentStore>((set) => ({ export const useTorrentStore = create<TorrentStore>((set) => ({
torrents: null, torrents: null,
torrentsLoading: false, torrentsLoading: false,
setTorrentsLoading: (loading: boolean) => set({ torrentsLoading: loading }), torrentsInitiallyLoading: false,
setTorrents: (torrents) => set({ torrents }), setTorrentsLoading: (loading: boolean) =>
set((prev) => {
if (prev.torrents == null) {
return { torrentsInitiallyLoading: loading, torrentsLoading: loading };
}
return { torrentsInitiallyLoading: false, torrentsLoading: loading };
}),
setTorrents: (torrents) =>
set((prev) => {
if (torrentsEquals(prev.torrents, torrents)) {
return {};
}
return { torrents };
}),
refreshTorrents: () => {}, refreshTorrents: () => {},
setRefreshTorrents: (callback) => set({ refreshTorrents: callback }), setRefreshTorrents: (callback) => set({ refreshTorrents: callback }),
})); }));

View file

@ -1867,7 +1867,7 @@ dependencies = [
[[package]] [[package]]
name = "librqbit" name = "librqbit"
version = "5.3.0" version = "5.4.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"axum", "axum",
@ -1894,6 +1894,7 @@ dependencies = [
"rand 0.8.5", "rand 0.8.5",
"regex", "regex",
"reqwest", "reqwest",
"rlimit",
"serde", "serde",
"serde_json", "serde_json",
"serde_urlencoded", "serde_urlencoded",
@ -3010,9 +3011,18 @@ dependencies = [
"winreg 0.50.0", "winreg 0.50.0",
] ]
[[package]]
name = "rlimit"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3560f70f30a0f16d11d01ed078a07740fe6b489667abc7c7b029155d9f21c3d8"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "rqbit-desktop" name = "rqbit-desktop"
version = "5.3.0" version = "5.4.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"base64 0.21.5", "base64 0.21.5",