React 最小設定とHooksの簡単サンプル

最近Reactをいじっているので忘れないためのメモ書きです。主な内容は以下。

  1. create-react-appを使わない最小限の環境構築
  2. React HooksのuseState,useEffectの超単純な使い方

特に1に関してはコチラを見ながら自分でやってみた内容をまとめただけです。

全コード(GitHub): Link

Environment (2021年3月)

  • Ubuntu 16.04
  • node v14.15.5
  • npm 6.14.11
  • react 17.0.1

環境構築

プロジェクトディレクトリの作成

1
2
mkdir app && cd app
npm init -y # package.json, package-lock.jsonが生成される

ライブラリインストール

1
2
3
npm install -D typescript webpack webpack-cli ts-loader html-webpack-plugin webpack-dev-server
npm install -D @types/react @types/react-dom
npm install -S react react-dom

設定ファイルの作成/編集

tsconfig.json

1
npx tsc --init

上記でtsconfig.jsonを作成後、"jsx": "react"のみの変更でとりあえず動く。
サーバアプリだと出力先ディレクトリ(outDir)や入力元ディレクトリ(include: ["src"])も変更するが、フロントエンドの場合はwebpackの方で設定するので基本不要。

webpack.config.js

基本的にコチラを真似ればOK。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
const HtmlPlugin = require('html-webpack-plugin')

module.exports = {
mode: "development",

entry: "./src/index.tsx",

output: {
path: `${__dirname}/dist`,
filename: "index.js"
},

module: {
rules: [
{
test: /\.tsx?$/,
use: "ts-loader"
}
]
},

resolve: {
extensions: [".ts", ".tsx", ".js", ".json"]
},

target: ["web", "es5"],

plugins: [
new HtmlPlugin({
template: './src/index.html'
})
],

devServer: {
contentBase: `${__dirname}/dist`,
port: 9000,
}
};

package.json

1
2
3
4
"scripts": {
"build": "webpack",
"start": "webpack serve"
}
  • npm run buildでビルド
  • npm run startwebpack.config.jsdevServerの項目で指定した設定でlocalhostサーバが起動する。

簡単な時計を作る

時刻を使う上でmomentが便利なのでインストール。

1
npm install -S moment

index.html

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>MyClockApp</title>
</head>

<body>
<div id="root"></div>
</body>
</html>

index.tsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import React, { useState, useEffect } from "react"
import ReactDOM from "react-dom"
import moment from "moment"

const App = () => {
const [currentDisp, setCurrentDisp] = useState("")

useEffect(() => {
setTimeout(() => {
setCurrentDisp(moment().format("YYYY/MM/DD hh:mm:ss"))
}, 1000)
})

return (
<div>
Today is {currentDisp}
</div>
)
}

ReactDOM.render(
<App />,
document.getElementById('root')
)
  • usetStateは状態変数(currentDisp)と、その変数に対するsetter関数(setCurrentDisp)のペアを返す
  • useEffectは描画更新に付随して実行される。第2引数に依存変数のリストを与えることで、「何が更新された時に実行して欲しいか」を制御できる。

参考