1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

手を動かしながら学ぶReact入門 2. Reactについて学ぶ

Last updated at Posted at 2021-02-02

WebフレームワークであるReactについて、実際に手を動かしながら学んでいきたいと思います。

1. Create React Appでプロジェクトの雛形を作成
2. Reactについて学ぶ ← ここ
3. 三目並べを関数コンポーネントで実装する

Reactについて学ぶ

先で作成したApp.jsと、index.jsを見てみましょう。

App.js
function App() {
  return (
    <h1>Hello World</h1>
  );
}

export default App;
index.js
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はコンパイル時に下記のように変換されます。いわゆるシンタックスシュガーというやつです。

App.js(コンパイル後)
function App() {
  return (
    React.createElement("h1", null, "Hello World");
  );
}

export default App;

createElementに変換されることで、DOMを作成しているわけですね。
<h1>タグ一つだけだったらこれだけでもいいかもしれませんが、階層構造になるとJSXがすごく見通しが良くなるのがわかると思います。

App.js
function App() {
  return (
    <div>
        <h1>Hello World</h1>
        <p>foo</p>
        <p>bar</p>
    </div>
  );
}

export default App;
App.js(コンパイル後)
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内で変数を扱うには波括弧でくくります。

App.js
const name = "Basio";
function App() {
  return (
    <h1>Hi {name}</h1> // -> Hi Basio
  );
}

export default App;

波括弧内は変数だけでなく、式や文も入れ込めます。

App.js
const count = 10;
function App() {
  return (
    <h1>Count is {count + 1}</h1> // -> Count is 11
  );
}

forで回してみる

波括弧でくくればJavaScriptの文を入れ込めるため、forループも可能です。

App.js
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というプロパティを受け取って、表示する内容が変わるコンポーネントです。

App.js
function Welcome(props) {
  return (
    <div>Hi {props.name}</div>
  );
}

export default Welcome;
index.js
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の内容が設定されていることがわかります。
image.png

ただし、このpropsについては一つ制約があり、propsは読み取り専用でなければならないです。
カウンターのように更新される値についてはpropsは使えないということですね。

state : 状態

じゃあどうするのさ、って時にstateを使用します。
stateは変更可能な値を格納でき、stateが変更されたタイミングで画面も自動的に更新されます。
propsでは実現できなかったカウンターコンポーネントを作ってみましょう。

setStateを使うことでstateの定義&初期化、state更新用関数の定義が行えます。

App.js
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;
index.js
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」ボタンをクリックすることでカウントが更新されるコンポーネントが実現できました。
image.png
stateを使うことで画面と紐付いた状態を実現することができていますね。

次は公式の三目並べを関数コンポーネントだけで実装していきたいと思います。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?