🐥

solid.jsに入門してみる

2023/04/18に公開

成果物

よくあるシンプルなカウンターを実装してみた。

ライブラリ

  • node.js 18.15.0
  • solid.js 1.6.10
  • tailwindcss 3.3.1
  • postcss 8.4.21
  • autoprefixer 10.4.14

実装してみる

まずは公式の手順に沿ってプロジェクトを作成する。

npx degit solidjs/templates/ts counter
cd counter
npm i

tailwindcssをインストールする。こちらも公式の通り。

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

※ここまででディレクトリ構成はこんな感じ。

counter/
  ├── dist/ #詳細は省略
  ├── node_modules/ #詳細は省略
  ├── src/ 
  │   ├── asset/
  │   │   └── favicon.ico
  │   ├── App.module.css
  │   ├── App.tsx
  │   ├── index.css
  │   ├── index.tsx
  │   └── logo.svg
  ├── .gitignore
  ├── index.html
  ├── package-lock.json
  ├── packeage.json
  ├── pnpm-lock.yaml
  ├── postcss.config.js
  ├── README.md
  ├── tainwind.config.js
  ├── tsconfig.json
  └── vite.config.ts

tailwind.config.jsを編集する

ファイルへのパスを通す。

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ["./src/**/*.{html,js,jsx,ts,tsx}"],
  theme: {
    extend: {},
  },
  plugins: [],
}

src/index.cssにtainwindcssのディレクティブを追加する

src/index.css
@tailwind base;
@tailwind components;
@tailwind utilities;

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
    'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
    sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

code {
  font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
    monospace;
}

ボタンコンポーネントを作成する

src直下にcomponentsフォルダを作成しその中にButton.tsxを作成する。
propsとしてボタンに表示するテキストとクリック時に実行される関数を渡す。

src/components/Button.tsx
import { Component, JSX } from "solid-js";

export const Button: Component<{
text: string,
action: JSX.EventHandler<HTMLButtonElement, MouseEvent>
}> = (props) => {
  return <button class="bg-indigo-700 font-semibold text-white py-2 px-4 mx-2 rounded" onClick={props.action} >
  {props.text}
  </button>;
};

App.tsxを編集する

App.tsxを編集してカウンターを実装する。
全体コードはこちら。

App.tsx
import { Component, createSignal } from 'solid-js';
import { Button } from './components/Button';

const [count, setCount] = createSignal<number>(0);

const increments = () => {
  setCount(c => c + 1)
}

const decrements = () => {
  setCount(c => c - 1)
}

const App: Component = () => {
  return (
    <>
      <div class="bg-white rounded-lg px-6 py-8 ring-1 ring-slate-900/5 shadow-xl max-w-xl mx-auto mt-8">
        <h1 class="text-6xl text-center">Counter</h1>
        <div class="text-center my-5 text-9xl">{count()}</div>
        <div class="grid grid-flow-col justify-stretch ">
          <Button text="-" action={decrements} />
          <Button text="+" action={increments} />
        </div>
      </div>
    </>
  );
};

export default App;

カウント数を保持するためにcreateSignalで変数を定義する。reactでいうuseState。

const [count, setCount] = createSignal<number>(0);

カウント数を増減するための関数を定義している。
setCountを使って新たな値をセットする。どちらの関数も直前の値から1を加算/減算している。

const increments = () => {
  setCount((prev) => prev + 1)
}

const decrements = () => {
  setCount((prev) => prev - 1)
}

※最終的なディレクト構成

counter/
  ├── dist/ #詳細は省略
  ├── node_modules/ #詳細は省略
  ├── src/ 
  │   ├── asset/
  │   │   └── favicon.ico
  │   ├── components
  │   │   └── Button.tsx
  │   ├── App.module.css
  │   ├── App.tsx
  │   ├── index.css
  │   ├── index.tsx
  │   └── logo.svg
  ├── .gitignore
  ├── index.html
  ├── package-lock.json
  ├── packeage.json
  ├── pnpm-lock.yaml
  ├── postcss.config.js
  ├── README.md
  ├── tainwind.config.js
  ├── tsconfig.json
  └── vite.config.ts

実行する

以下のコマンドで実行。ブラウザでlocalhost:3000にアクセスすればアプリケーションが表示される。
ボタンが正しく動けば完成!

npm run start

Discussion