Skip to content

簡単な機能を作る

src/App.tsxを開いてみましょう。
こんなコードが書いてあると思います。

src/App.tsx
import './App.css'
function App() {
return (
<>
<h1>Hello, React</h1>
</>
)
}
export default App

このファイルのApp関数には、ウェブサイトに表示するものが書いてあります。
試しに、文言を変えてみましょう。
<h1>Hello, React</h1><h1>しりとりアプリ</h1>に変えてみてください。

src/App.tsx
import './App.css'
function App() {
return (
<>
<h1>Hello, React</h1>
<h1>しりとりアプリ</h1>
</>
)
}
export default App

表示が「しりとりアプリ」に変わったと思います。

<input>タグというHTMLタグを使えば、よく見る入力欄を作れます。
追加してみましょう。

src/App.tsx
import './App.css'
function App() {
return (
<>
<h1>しりとりアプリ</h1>
<input type="text" />
</>
)
}
export default App

type="text"はタグの 属性(attributes) です。要素に対して表示形式などを指定できます。

HTMLタグの基本的な文法
<タグ名 属性名1=属性値1 属性名2=属性値2></タグ名>

<input>タグは、type属性を指定することで、様々な形式の入力欄を作ることができます。

<input>typeにどんな種類があるかは以下のページから実際に触って確認できます。

<input>: HTML 入力要素 - HTML: ハイパーテキストマークアップ言語 | MDN
<input> は HTML の要素で、ユーザーからデータを受け取るための、ウェブベースのフォーム用の操作可能なコントロールを作成するために使用します。端末とユーザーエージェントによりますが、広範に渡る種類のデータ入力やコントロールウィジェットが利用できます。<input> 要素は入力型と属性の組み合わせの数が非常に多いため、HTML の中で最も強力かつ最も複雑な要素の一つです。
<input>: HTML 入力要素 - HTML: ハイパーテキストマークアップ言語 | MDN favicon developer.mozilla.org
<input>: HTML 入力要素 - HTML: ハイパーテキストマークアップ言語 | MDN

アプリを作るには、何が入力されたか検知する必要があります。
そのためには、onChangeという「イベント」を使います。

イベントとは、何かが起きたことを表します。
文字が入力されるなど、値が変わればonChangeイベント
クリックされたらonClickイベント
などたくさんあります。

Reactでは、on<イベント名>={<関数>}とすると、イベントがトリガー(発生、発火)したときに、実行する関数を指定できます。
以下のように書き換えてみましょう。

src/App.tsx
import './App.css'
function App() {
return (
<>
<h1>しりとりアプリ</h1>
<input type="text" />
<input
type="text"
onChange={(event) => {
console.log(event.target.value);
}}
/>
</>
)
}
export default App

JavaScript/TypeScriptでは(<引数>)=><処理>という形で、関数を書くことができます。(ラムダ式という)
それをinputタグのonChange属性に指定することで、入力が変更されたときにその関数を実行させることができます。

今回は変更後の値(event.target.value)をconsole.log()関数でブラウザのコンソールと呼ばれる場所に表示させています。

ブラウザのコンソールは、F12キー(または Ctrl+Shift+I)を押すと開くことができる「DevTool」(開発者ツール)の中にあります。
F12キーを押して、Consoleタブを選択してみてください。

何か文字を入力してみると、コンソールに入力した文字が表示されると思います。

「react」は5文字なので5回onChangeイベントがトリガーします。

次は、入力した文字を画面に表示させてみましょう。

src/App.tsx
import { useState } from "react";
import "./App.css";
function App() {
const [text, setText] = useState("");
return (
<>
<h1>しりとりアプリ</h1>
<input
type="text"
onChange={(event) => {
console.log(event.target.value);
setText(event.target.value);
}}
/>
<p>{text}</p>
</>
);
}
export default App;

Reactには「状態(State)」という重要な概念があります。
Reactでは。useStateという関数を使って「記憶」をさせることができます。
(なぜ普通の変数ではだめなのかは、後で説明します)

useStateを使うにはまず、import文を使って、useStateを使う旨を宣言します。

import { useState } from "react";

importできたら、useStateを使って状態を作ります。

const [text, setText] = useState("");

useState("")""は初期値を表します。

やっていることは変数の初期化と一緒です。

C言語の変数初期化
char text[100] = "";

useStateで作った状態をconstを使って変数に代入しています。
const [text, setText]のように、[]で囲むことで、2つの変数を同時に作ることができます。
textは状態の値を表し、setTextは状態を変更するための関数です。

普通の変数のように先程の例では、1番目にあるtextと書けば使えます。

text

ちなみにWebサイトの中に表示させるには、<p>{text}</p>のように{}で囲むことで、値を表示できます。

<p>{text}</p>

状態の値を変更するには、2番目のsetText関数を使います。

setText("新しい値");

この関数を実行すると、textの値が「"新しい値"」に書き換わります。

うまくコードがかけていれば、入力した文字が即座に入力欄の下に表示されると思います。

(おまけ)なぜ useState を使う必要があるのか

useStateを使わずに、ほぼ同じコードを書いてみました。

import { useState } from "react";
import "./App.css";
function App() {
let text = "";
return (
<>
<h1>しりとりアプリ</h1>
<input
type="text"
onChange={(event) => {
text = event.target.value;
}}
/>
<p>{text}</p>
</>
);
}
export default App;

letは変数を再代入可能なものとして宣言するものです。

このコードを試してみると入力された文字が表示されません。

なぜでしょうか?理由はいくつかあります。

Reactは普通の変数の値の変化を検知できません。
つまり、変数の値が変わろうがReactは知ったこっちゃないわけです。
そのため、textの値が変わっても、Reactはそれを検知できず、画面を更新(再レンダリング)しません。
なので、setTextのように、更新する専用の関数を呼び出してあげることで、Reactに「この値が変わったから、再レンダリングお願いします」と伝える必要があります。

ReactではApp関数のようにHTMLを返す関数を「コンポーネント」と呼びます。
実は、コンポーネント関数はレンダリングされるたびに関数自体が再実行されます。
そのため、その関数内にlet text = "";と書くと、毎回text""で初期化されてしまいます。
なので、useStateを使って、Reactに「これは状態だから別の場所に記憶しておいてね」と伝える必要があります。