【React】基礎

## Reactとは
> React はユーザーインターフェイスを構築するための、宣言型で効率的で柔軟な JavaScript ライブラリです。複雑な UI を、「コンポーネント」と呼ばれる小さく独立した部品から組み立てることができます。 

> React (リアクト) は、Facebookとコミュニティによって開発されているユーザインタフェース構築のためのJavaScriptライブラリである。React.jsまたはReactJSの名称でも知られている。
>
> Reactはシングルページアプリケーションやモバイルアプリケーションの開発におけるベースとして使用することができる。
  
※[Wikipedia - React](https://ja.wikipedia.org/wiki/React) より

## Reactの基本
以下、記述しているコードはReact公式ドキュメントや公式チュートリアルを引用、もしくはベースにしています。

### 基本文法
index.jsで、`ReactDOM.render`でレンダリングするコンポーネントと、レンダリングする箇所を定義。 
この例では、Appというコンポーネントに定義されたReact要素を、ルートDOMノード（index.htmlのid="root"の要素）にレンダリングするよう定義しています。

```html:public/index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="logo192.png" />
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>
```

```react:src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root')); // ルートDOMノードにAppコンポーネントをレンダリングするよう定義
```

コンポーネント定義の中のreturnで返されるReact要素（JSX）がレンダリングする内容。
（※関数コンポーネントのため省略されていますが、正確には`render()`メソッドが返すReact要素がレンダリングする内容）
エクスポートすることで、他ファイルからこのコンポーネントを呼び出すことができるようになります。

```react:src/App.js
import React from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
  return ( // レンダリングする内容
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App; // コンポーネントをエクスポート
```

### コンポーネント
#### クラスコンポーネント
`React.Component`を継承したクラスで定義されたコンポーネント。
後述する状態（state）やライフサイクルを持つことができます。

```react
import React from 'react';
class App extends React.Component {  // React.componentを継承するクラスの定義
  render() {  // JSXを戻り値とするrenderメソッドを定義
    return (
      <h1>Hello World</h1>
    );
  }
}

export default App;
```

#### 関数コンポーネント
クラスコンポーネントと違い、状態（state）やライフサイクルを持たないコンポーネントをよりシンプルに記述したもの。
constで変数定義などはできますが、基本的に`render()`メソッドのみであるため、`render()`の記述が省略できます。


最近の傾向では、なるべく関数コンポーネントを使用する方向であるようですが、状態（state）やライフサイクルを持つことができないため、関数コンポーネントもクラスコンポーネントと同等の機能を有せるようにと`recompose`や`React Hooks`が生まれたそうです。

```react
import React from 'react';
function App() {
  return (
      <h1>Hello World</h1>
  );
}

export default App;
```

アロー関数で以下のようにも書くことができます。

```react
import React from 'react';
const App = () => {
  return (
      <h1>Hello World</h1>
  );
}

export default App;
```

また変数定義などがなく、純粋に`render()`メソッドのみの場合は、さらに`return`も省略することができます。

```react
import React from 'react';
const App = () => (
  <h1>Hello World</h1>
)

export default App;
```

### JSX
#### 基本
コンポーネントのrender()メソッド内に記述するHTMLに似た構文で、React要素を生成するもの。
Babelでのコンパイル時に`React.createElement() `形式に変換されます。
そのため、以下のコードは等価のものになります。

```react
const element= (
  <h1 className="title">
    Hello, world!
  </h1>
);
```

```react
const element = React.createElement(
  'h1',
  {className: 'title'},
  'Hello, world!'
);
```

また、JSXでは**一つのReact要素**を返す必要があります。
複数の要素から構成される場合は、divで囲うなどして、一つのReact要素を返すようにしましょう。

NGな例

```react
render() {
  return (
    <h1>h1です</h1>
    <h2>h2です</h2>
    <p>pです</p>
  )
}
```

OKな例

```react
render() {
  return (
    <div>
      <h1>h1です</h1>
      <h2>h2です</h2>
      <p>pです</p>
    </div>
  );
}
```

JSXはHTMLと似ていますが閉じタグに関しては注意が必要。
imgタグのようにHTMLでは閉じタグが必要なかったものについては、末尾に`/`とつけて閉じる必要があります。

```react
<img src='画像URL' />
```

#### React.Fragment
場合によっては、複数要素をまとめるためにdivで囲うことで支障が出ることもあります。
そういったときは`React.Fragment`というものを使うことができ、DOMに余分なノードを追加することなく子要素をまとめられます。
また、`React.Fragment`では後述する`key`プロパティを持つことができます。


```react
render() {
  return (
    <React.Fragment>
      <h1>h1です</h1>
      <h2>h2です</h2>
      <p>pです</p>
    </React.Fragment>
  );
}
```
短縮記法で以下のようにも書くことができますが、こちらでは`key`プロパティを持つことができないので注意が必要です。

```react
render() {
  return (
    <>
      <h1>h1です</h1>
      <h2>h2です</h2>
      <p>pです</p>
    </>
  );
}
```

#### 変数の埋め込み
JSX内に変数を埋め込む際は`{}`で囲って記述します。

```react
const name = 'Yamada Taro';
const element = <h1>Hello, {name}</h1>;
```

なお、デフォルトでは、React DOMはJSXに埋め込まれた値をレンダリングされる前にエスケープするため、以下のようにユーザーの入力を受け付ける場合でも、XSSなどインジェクション攻撃を防ぐことができます。

```react
const title = response.potentiallyMaliciousInput;
const element = <h1>{title}</h1>;
```

#### 命名規則
要素のプロパティに関してはキャメルケース。
例として、class は`className`となり、tabindex は`tabIndex`となります。

#### 条件付きレンダー
論理値 or 論理式と&&の組み合わせで、条件によってレンダリングする内容の切り替えができます。

```react
render() {
    const flg = true;
    return (
      <div>
        {/* flg変数がtrueの時のみレンダリング */}
        {flg && <p>フラグ：true</p>} 
        {/* flg変数がfalseの時のみレンダリング */}
        {!flg && <p>フラグ：false</p>}
      </div>
    )
  }
```
三項演算子を使用した例

```react
render() {
    const flg = true;
    return (
      <div>
        {flg ? <p>フラグ：true</p> : <p>フラグ：false</p>}
      </div>
    )
  }
```
以上　次回はstateに触れます。