Skip to content

Commit 4499aae

Browse files
authored
Merge pull request #168 from takker99:use-effect
refactor: Reduce the number of useEffect() as less as possible
2 parents a2c3ec1 + 2971222 commit 4499aae

File tree

2 files changed

+55
-60
lines changed

2 files changed

+55
-60
lines changed

useBubbleData.ts

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useLayoutEffect, useState } from "./deps/preact.tsx";
1+
import { useEffect, useState } from "./deps/preact.tsx";
22
import { load, subscribe, unsubscribe } from "./bubble.ts";
33
import { createDebug } from "./debug.ts";
44
import { ID } from "./id.ts";
@@ -8,35 +8,19 @@ const logger = createDebug("ScrapBubble:useBubbleData.ts");
88

99
/** bubbleデータを取得するhooks
1010
*
11-
* @param title 取得したいbubbleのタイトル
12-
* @param projects 取得先projectのリスト
13-
* @return bubble
11+
* @param pageIds 取得するページのID
12+
* @returns bubble data
1413
*/
1514
export const useBubbleData = (
1615
pageIds: readonly ID[],
1716
): readonly Bubble[] => {
18-
const [bubbles, setBubbles] = useState<readonly Bubble[]>([]);
19-
20-
useLayoutEffect(() => {
21-
const update = () => {
22-
setBubbles(() => {
23-
const bubbles = [...load(pageIds)].flatMap((bubble) =>
24-
bubble ? [bubble] : []
25-
);
26-
27-
// debug用
28-
logger.debug(
29-
`Required: ${pageIds.length} pages, ${bubbles.length} found`,
30-
bubbles,
31-
);
32-
return bubbles;
33-
});
34-
};
35-
36-
// データの初期化
37-
update();
17+
const [bubbles, setBubbles] = useState<readonly Bubble[]>(
18+
makeBubbles(pageIds),
19+
);
3820

39-
// データ更新用listenerの登録
21+
// データ更新用listenerの登録
22+
useEffect(() => {
23+
setBubbles(makeBubbles(pageIds));
4024

4125
let timer: number | undefined;
4226
/** ページデータを更新する */
@@ -45,7 +29,7 @@ export const useBubbleData = (
4529
clearTimeout(timer);
4630
timer = setTimeout(() => {
4731
logger.debug(`Update ${pageIds.length} pages`);
48-
update();
32+
setBubbles(makeBubbles(pageIds));
4933
}, 10);
5034
};
5135

@@ -58,3 +42,16 @@ export const useBubbleData = (
5842

5943
return bubbles;
6044
};
45+
46+
const makeBubbles = (pageIds: readonly ID[]): readonly Bubble[] => {
47+
const bubbles = [...load(pageIds)].flatMap((bubble) =>
48+
bubble ? [bubble] : []
49+
);
50+
51+
// debug用
52+
logger.debug(
53+
`Required: ${pageIds.length} pages, ${bubbles.length} found`,
54+
bubbles,
55+
);
56+
return bubbles;
57+
};

useBubbles.ts

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useCallback, useEffect, useState } from "./deps/preact.tsx";
1+
import { useCallback, useState } from "./deps/preact.tsx";
22
import { Position } from "./position.ts";
33
import { LinkType } from "./types.ts";
44
import { Scrapbox } from "./deps/scrapbox.ts";
@@ -54,19 +54,6 @@ export const useBubbles = (): [
5454
BubbleOperators,
5555
...BubbleSource[],
5656
] => {
57-
const [sources, setSources] = useState<Source[]>([]);
58-
59-
const change = useCallback(
60-
(
61-
depth: number,
62-
source?: Source,
63-
) =>
64-
setSources((old) =>
65-
source ? [...old.slice(0, depth), source] : [...old.slice(0, depth)]
66-
),
67-
[],
68-
);
69-
7057
const [bubbles, setBubbles] = useState<[
7158
BubbleOperators,
7259
...BubbleSource[],
@@ -75,26 +62,37 @@ export const useBubbles = (): [
7562
hide: () => change(0),
7663
}]);
7764

78-
// 操作函数や他のbubbleデータから計算される値を追加する
79-
useEffect(() => {
80-
// 更新されたbubble以外は、objectの参照を壊さずにそのまま返す
81-
setBubbles((
82-
[first, ...prev],
83-
) => [
84-
first,
85-
...sources.map((source, i) =>
86-
source === prev.at(i)?.source ? prev.at(i)! : ({
87-
source,
88-
parentTitles: [
89-
scrapbox.Page.title ?? "",
90-
...sources.slice(0, i).map((source) => source.title),
91-
],
92-
bubble: (source: Source) => change(i + 1, source),
93-
hide: () => change(i + 1),
94-
})
95-
),
96-
]);
97-
}, [sources]);
65+
const change = useCallback(
66+
(
67+
depth: number,
68+
source?: Source,
69+
) => {
70+
// 操作函数や他のbubbleデータから計算される値を追加する
71+
// 更新されたbubble以外は、objectの参照を壊さずにそのまま返す
72+
setBubbles((
73+
[first, ...prev],
74+
) => [
75+
first,
76+
...(
77+
source
78+
? [
79+
...prev.slice(0, depth),
80+
source === prev.at(depth)?.source ? prev.at(depth)! : ({
81+
source,
82+
parentTitles: [
83+
scrapbox.Page.title ?? "",
84+
...prev.slice(0, depth).map((bubble) => bubble.source.title),
85+
],
86+
bubble: (source: Source) => change(depth + 1, source),
87+
hide: () => change(depth + 1),
88+
}),
89+
]
90+
: [...prev.slice(0, depth)]
91+
),
92+
]);
93+
},
94+
[],
95+
);
9896

9997
return bubbles;
10098
};

0 commit comments

Comments
 (0)