0%

SolidJS: 強制的にコンポーネントを再描画する

logo.svg

SolidJS で強制的にコンポーネントを再描画する方法。

Signal の値をキーとして使用して、キーを変更することにより、コンポーネントを再描画する。

ここでは、「再描画」ボタンをクリックしたときに、1 秒ごとにカウントをインクリメントする以下の CountingComponent コンポーネントを再描画する。

CountingComponent.jsx:

1
2
3
4
5
6
7
8
9
10
11
12
13
import { createSignal, onCleanup } from "solid-js";

const CountingComponent = () => {
const [count, setCount] = createSignal(0);
const interval = setInterval(
() => setCount(c => c + 1),
1000
);
onCleanup(() => clearInterval(interval));
return <div>Count value is {count()}</div>;
};

export default CountingComponent;

環境

  • SolidJS 1.5.1

方法 1: For コンポーネントを使用する

App.jsx:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { createSignal, For } from "solid-js";
import CountingComponent from "./CountingComponent";

const App = () => {
const [key, setKey] = createSignal([{}]);
const rerender = () => setKey([{}]);

return (
<>
<For each={key()}>{() => <CountingComponent />}</For>
<button type="button" onClick={rerender}>
再描画
</button>
</>
);
};

export default App;

Solid Playground

キーは、項目が 1 つの配列である必要がある。

方法 2: For コンポーネントをラップしたコンポーネントを使用する

For コンポーネントをラップした Key コンポーネントを使用する。

Key.jsx:

1
2
3
4
5
6
7
8
9
import { createMemo, For } from "solid-js";

const Key = (props) => {
const key = createMemo(() => [props.is()]);
const fn = props.children;
return <For each={key()}>{fn}</For>;
};

export default Key;

App.jsx:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { createSignal } from "solid-js";
import CountingComponent from "./CountingComponent";
import Key from "./Key";

const App = () => {
const [key, setKey] = createSignal({});
const rerender = () => setKey({});

return (
<>
<Key is={key}>{() => <CountingComponent />}</Key>
<button type="button" onClick={rerender}>
再描画
</button>
</>
);
};

export default App;

Solid Playground

方法 3: 独自のコンポーネントを使用する

For コンポーネントを使用しない独自の Key コンポーネントを使用する。

App.jsx は方法 2 と同じ。

Key.jsx:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { createRoot, createMemo, onCleanup, on } from "solid-js";

const Key = (props) => {
const key = props.is;
const fn = props.children;
let disposer;
onCleanup(() => disposer && disposer());

return createMemo(
on(key, () => {
disposer && disposer();
return createRoot((dispose) => {
disposer = dispose;
return fn();
});
})
);
};

export default Key;

Solid Playground