Open5

ReactユーザーのSolidJSメモ

t-yngt-yng

状態管理

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>
  );
t-yngt-yng

リストの描画

Forコンポーネントを利用する。keypropsの指定は不要

<For each={todos()}>{(todo) => <span>{todo}</span>}</For>
t-yngt-yng

propsは分割代入できない

SolidJSではpropsを分割代入で受け取るとリアクティブ性が損なわれる
https://www.solidjs.com/guides/rendering#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>
  );
}
t-yngt-yng

条件付きレンダリング

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>
t-yngt-yng

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
  );
  ...
);