WebフレームワークであるReactについて、実際に手を動かしながら学んでいきたいと思います。
1. Create React Appでプロジェクトの雛形を作成
2. Reactについて学ぶ ← ここ
3. 三目並べを関数コンポーネントで実装する
Reactについて学ぶ
先で作成したApp.jsと、index.jsを見てみましょう。
function App() {
return (
<h1>Hello World</h1>
);
}
export default App;
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
この関数Appが一つのコンポーネントとしてindex.jsの中で呼び出されています。
index.jsはindex.htmlのroot
というIDの要素に対してAppコンポーネントを適用しているので、結果としてAppコンポーネント(この場合だとHello World)が表示されたわけですね。
関数Appの中を見ていると、なにやらJavaSciptの関数がHTMLのタグを返していますね。
この少し見慣れない構文をJSXと言います。
JSX
上記のJSXはコンパイル時に下記のように変換されます。いわゆるシンタックスシュガーというやつです。
function App() {
return (
React.createElement("h1", null, "Hello World");
);
}
export default App;
createElementに変換されることで、DOMを作成しているわけですね。
<h1>
タグ一つだけだったらこれだけでもいいかもしれませんが、階層構造になるとJSXがすごく見通しが良くなるのがわかると思います。
function App() {
return (
<div>
<h1>Hello World</h1>
<p>foo</p>
<p>bar</p>
</div>
);
}
export default App;
function App() {
return (
React.createElement("div", null, React.createElement("h1", null, "Hello World"), React.createElement("p", null, "foo"), React.createElement("p", null, "bar"));
);
}
export default App;
変数を使う
JavaScriptでDOMを定義できるので、もちろん変数を使うことができます。
JSX内で変数を扱うには波括弧でくくります。
const name = "Basio";
function App() {
return (
<h1>Hi {name}</h1> // -> Hi Basio
);
}
export default App;
波括弧内は変数だけでなく、式や文も入れ込めます。
const count = 10;
function App() {
return (
<h1>Count is {count + 1}</h1> // -> Count is 11
);
}
forで回してみる
波括弧でくくればJavaScriptの文を入れ込めるため、forループも可能です。
function App() {
const array = ['foo', 'bar', 'baz'];
return (
<ul>
{array.map(element=>{
return <li>{element}</li>;
})
// -> <li>foo</li><li>bar</li><li>baz</li>
}
</ul>
);
}
export default App;
Component
最初にも記載していますが、Reactではコンポーネントという単位で要素を作成し、それを組み合わせてUIを構築していきます。
コンポーネントは以前からあるクラスコンポーネントとReact 16.8以降で導入された関数コンポーネントの2つがありますが、本稿では関数コンポーネントのみ扱います。
理由は他の人が色々挙げられていますが、個人的にJavaScriptのthisが非常にわかりにくいというのが大きなところです。
参考:Reactでクラスコンポーネントより関数コンポーネントを使うべき理由5選
今の所実装しているコンポーネントは、ただJavaScriptでHTMLのコードをまとめただけのものですね。
コンポーネント(部品)というからには、作成時にプロパティを与えたり、状態をもたせたり、アクションを定義したりということが必要になってくると思います。
安心してください、もちろんそんな機能もコンポーネントには含まれています!
props:プロパティ
コンポーネントに初期値を渡したいときはprops(プロパティの意)を使用します。
今までAppという名前のコンポーネントで通してきましたが、わかりやすいように今回はWelcomeという名前に変更します。
Welcomeコンポーネントはnameというプロパティを受け取って、表示する内容が変わるコンポーネントです。
function Welcome(props) {
return (
<div>Hi {props.name}</div>
);
}
export default Welcome;
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import Welcome from './App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<Welcome name="foo"/>
<Welcome name="bar"/>
<Welcome name="baz"/>
</React.StrictMode>,
document.getElementById('root')
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
このように、propsの内容が設定されていることがわかります。
ただし、このpropsについては一つ制約があり、propsは読み取り専用でなければならないです。
カウンターのように更新される値についてはpropsは使えないということですね。
state : 状態
じゃあどうするのさ、って時にstateを使用します。
stateは変更可能な値を格納でき、stateが変更されたタイミングで画面も自動的に更新されます。
propsでは実現できなかったカウンターコンポーネントを作ってみましょう。
setState
を使うことでstateの定義&初期化、state更新用関数の定義が行えます。
import React, {useState} from 'react';
function Counter() {
const [count, setCount] = useState(0); // 初期値0でcountを初期化 & state更新用関数setCountを定義
return (
<React.Fragment>
<p>Count : {count}</p>
<button onClick={()=>{setCount(count + 1)}}>
Count Up
</button>
</React.Fragment>
);
}
export default Counter;
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import Counter from './App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<Counter/>
</React.StrictMode>,
document.getElementById('root')
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
「Count Up」ボタンをクリックすることでカウントが更新されるコンポーネントが実現できました。
stateを使うことで画面と紐付いた状態を実現することができていますね。
次は公式の三目並べを関数コンポーネントだけで実装していきたいと思います。