Open5
ReactユーザーのSolidJSメモ
状態管理
useState
ReactにおけるuseStateはSolidJSではcreateSignalを使う。
Reactと異なり値でなくgetterとなることに注意
const Counter = () => {
const [count, setCount] = createSignal(0);
return (
<>
<button onClick={() => setCount(count => count + 1)}>クリック</button>
<span>{count()}</span>
</>
);
}
オブジェクト比較
デフォルトではReactと同様に厳密比較になるが、{equals: false}
を指定することで値をセットしたら強制的に更新させることが可能
const [current, setCurrent] = createSignal({ count: 0 }, { equals: false });
const handleClick = () => {
setCurrent((current) => {
// equals: false なら同じオブジェクトでも更新がされる
current.count += 1;
return current;
});
};
return (
<div>
<button onClick={handleClick}>クリック</button>
<span>{current().count}</span>
</div>
);
リストの描画
For
コンポーネントを利用する。key
propsの指定は不要
<For each={todos()}>{(todo) => <span>{todo}</span>}</For>
propsは分割代入できない
SolidJSではpropsを分割代入で受け取るとリアクティブ性が損なわれる
クセで無意識に分割代入で書いてしまうことがあるので、結構なハマりポイント
Viewが更新されないバグに遭遇したら、これを疑うと良い
const SplitedCounter = ({ count }) => <div>{count}</div>
const Counter = (props) => <div>{props.count}</div>
const App = () => {
const [count, setCount] = createSignal(0);
return (
<button onClick={() => setCount(count => count + 1)}>クリック</button>
{/* 分割代入でpropsを受け取ると再描画されない */}
<SplitedCounter count={count()} />
{/* 分割代入せずにpropsを受け取る場合は再描画される */}
<Counter count={count()} />
)
}
分割して取得したい場合
splitProps
を利用する。
const Component = (props) => {
const [local, others] = splitProps(props, ["class"]);
return (
<div class={local.class}>
<span {...others}>その他</span>
</div>
);
}
条件付きレンダリング
Reactと同じようにブーリアン式や3項演算子で記述できる。
{visible && <button>ボタン</button>}
{user.loggedIn ? <button>Log out</button> : <button>Log in</button>}
Show
コンポーネントを利用することで、読みやすくJSXを記述できる。
<Show when={user.loggedIn} fallback={<button>Log in</button>}>
<button>Log out</button>
</Show>
default Props の設定
SolidJSでは分割代入によるpropsの受け取りができないので、mergeProps
関数を利用してpropsのデフォルト値を設定する。
Reactと比べると少しコード量が増える
type FeatureVisible = {
add?: boolean;
remove?: boolean;
}
type ToolbarProps = {
visible?: FeatureVisible;
}
const Toolbar: Component<ToolbarProps> = (_props) => {
// デフォルト値のオブジェクトについて上手く型推論が効かないのでジェネリクスで型を指定する必要あり
const props = mergeProps<ToolbarProps[]>(
{ visible: { add: true, remove: true },
_props
);
...
);