デザイナーでも分かる範囲のReact、その書き方と学び方

## これは何

- 「デザイナーもReact書いてくださいよ」って空気になったときに読むと役立つかもしれない記事です
- 基本的に筆者が学んだ流れを記載しています
    - そのため、世間一般のベストプラクティスではないと思います
    - エンジニアの方から見ると邪道な流れ・説明の仕方かもしれませんが、デザイナーに教える上での分かりやすさを重視していますのでご了承ください
- [この記事の中で使っているコードはこちらのリポジトリで公開しています](https://github.com/xrxoxcxox/qiita-react-for-designer)
    - コミットを辿ってもらえれば、各セクションの内容が全て見れます
- ※言い訳がましいですが、筆者もReactに精通している程ではなく「デザイナーにしては割と知ってる」レベルです
    - もし説明に間違いや不足があれば編集リクエストをお願いします :pray:

## 対象読者

- Web or UIデザイナー
- HTMLとCSSは普通に書けるけど、Reactはほぼ全く触ったことがない人
- 1人で完全に実装したいってほどではないけど、簡単な部分は書けるようになりたいと思っている人
- メイン対象はデザイナーなものの、初心者向けの内容ではあるので「新人プログラマ」も対象になるかもしれません

https://qiita.com/official-events/63aa63fd921659fb3b5d

## 筆者はどんな人

普段の業務ではUIのモックアップを作って、ある程度はReactでのコーディングもしています。
また、業務レベルではありませんが自分のポートフォリオサイトは全てReactで書いています。

## Reactの概念について

概念を説明するといっても、深い部分までは扱いません。
あくまでデザイナー向け、かつ、不慣れな人でもパンクしない程度の内容にとどめます。

上記の関係で「Reactに限らない説明」も多いです。

### コンポーネントを組み合わせてインターフェースを作成できる

- ボタン・タブ・リスト……UIの種別を問わず、一度定義すればそれを繰り返し使える
    - 同じものを何回も作らなくて良い
- FigmaやSketchなどのツールを用いてインターフェースを作るときの考え方と非常に似ている[^1]
    - 慣れれば、UIツール上でコンポーネントを作っている最中に、コードでのコンポーネントの実装方法も想像できる

[^1]: UIツールに実装されるよりも前から、プログラミングの世界にはコンポーネントのような概念がありました。デザイナーの方が後発です。（念のため補足）

### 色々な場所が変化するインターフェースを作成しやすい

- HTMLやCSSだけでサイトを作るのはかなり大変
    - 「ログインしていたら」とか「商品を買い物かごに入れていたら」といった、任意の条件にあわせたインターフェースの変化は上手く表現できない
    - HTMLだけだったら「登録されているユーザー情報を100人分表示する」場面では100回繰り返して書く必要がある
    - それ以外にも色々……
- Reactなら上記の「条件の違い」や「繰り返し」も表現できる[^2]
    - HTMLやCSSだけではできないことができるようになる
    - 効率の良いコードを書けるようになる

[^2]: これはReactに限らない話。

## Reactを触っていく順番

公式のチュートリアルとは全然違う順番ですが、デザイナーならこういう順番で触れるのが良いのではないでしょうか。

私がいつも伝える上で大事にしているのは「何も分からない……」と諦めの感情を抱かせないようにすることです。
「完全に理解した」と調子に乗るのも良くありませんが「意外と理解できる、楽しいぞ！」と思えるのが重要だと思います。

### HTMLもどきとCSSもどきだけを触れるようになる

デザイナーもReactを触ると言っても、最初のうちはHTMLもどきとCSSもどきを触れるようになるだけでも十分かと思います。
簡単なスタイル調整や文言の修正をエンジニアから巻き取れるだけでも、チームの作業スピードは上がるんじゃないでしょうか。

それにしても`もどき`ってなんだよって話ですよね。
細かい説明をしだすと難しくなるので、実際のコードを見てください。

[Create React App](https://ja.reactjs.org/docs/create-a-new-react-app.html)というスターターキットのようなものがあり、そこで生成されるコードをアレンジして例に出します。

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

const firstName = "John"
const lastName = "Doe"
const fullName = `${firstName} ${lastName}`

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Hello, {fullName}
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;
```

![Hello, John Doeと書かれた画面のスクリーンショット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/06eb28d8-01b5-3102-53a2-2ce0d755abea.png)

見た目はこんな感じです。

`App.js`において`import`や`const`や`function`や`export`は見慣れないかもしれません。
しかし`return`以降は見覚えがありますよね？

そう、ほぼHTMLなんです。

現段階で微妙にHTMLと違うのは以下の2点のみ。

1. `class`ではなく`className`と書かれている
1. `img`タグの`src`や、`p`タグの中で`{}`を使って書かれている箇所がある（`{logo}`と`{userName}`）

#### classNameについて

Reactの世界では`class`という単語はCSS以外の場所で使われています。
そのため`CSSのクラス名`を指定する際には、`class`ではなく`className`と書く必要があります
若干違和感を覚えるかもしれませんが、これは暗記するしかありません。

ちなみに似た話で`label`と`input`を紐付ける際に、HTMLでは`for`を使いますが、Reactでは`htmlFor`を使います。
こちらも違和感はあると思いますが「Reactではそうやって書くんだな」と割り切って覚えていただきたいです。

ここで「冒頭で出ていた『CSSもどき』って`class`が`className`に変わるだけってこと？」と思われる方もいるかもしれません。
半分正解で、半分不正解です。
Reactにおいてスタイリングを施す方法はかなりたくさんあるため、一概には言えないのです。

例えば「font-sizeが20pxで赤色の文字」をスタイリングするだけでも、次のような方法があります。

##### 例1 インラインスタイル

```react:例1
// インラインスタイル
function Example1() {
  return (
    <p style={{ fontSize: 20, color: "#f00" }}>スタイリングの例</p>
  )
}
```

##### 例2 普通のCSSやSassを使う

```react:例2
// React側のコード
import './style.css'

function Example2() {
  return (
    <p className="foo">スタイリングの例</p>
  )
}
```

```css:例2
/* CSS側のコード */
.foo {
  font-size: 20px;
  color: #f00;
}
```

##### 例3 CSS Modulesを使う

```react:例3
// React側のコード
import styles from './style.css'

function Example3() {
  return (
    <p className={styles.foo}>スタイリングの例</p>
  )
}
```

```css:例3
/* CSS側のコード */
.foo {
  font-size: 20px;
  color: #f00;
}
```

##### 例4 CSS in JSを使う（ここではEmotion）

```react:例4
import { css } from "@emotion/react"

function Example4() {
  return (
    <p css={foo}>スタイリングの例</p>
  )
}

const foo = css({
  fontSize: 20,
  color: "#f00"
})
```

たくさん例を出しましたがビビらせたい訳ではありません。
この例以外にもまだまだ色々な書き方があり、網羅的に説明するのが難しいことをお伝えしたいだけです。

更に言えば例1~4を見て頂ければ分かるとおり、それぞれ微妙に書き方は違うものの「ほぼCSS」ですよね？
そのため、使っているものさえ分かれば後は慣れるだけです。

「ウチってスタイリングには何を使ってるんですか？」と聞けば、エンジニアのみなさんが教えてくれることでしょう。

#### `{}`の使用について

HTMLを書いていて、`{}`が何かの役割を担うことはありませんよね？
ですが、Reactにおいては大活躍します。

HTMLもどきの中で`{}`が出てきたら「このカッコの中ではJavaScriptが動いているんだな」と捉えてください。

`img`タグでは

```react
<img src={logo} className="App-logo" alt="logo" />
```

と書いてありますが、先ほどのコードの1行目には

```react
import logo from './logo.svg';
```

と書いてあります。

これらを踏まえて`img`タグに書いてある内容をHTMLに翻訳（？）すると以下のようになります。

```react
<img src='./logo.svg' className="App-logo" alt="logo" />
```

`'./logo.svg'`の場所にあるファイルを`{logo}`という書式で呼び出せるようになっているんですね。

また、コードの最初の方には以下の記述があります。

```react
const firstName = "John"
const lastName = "Doe"
const fullName = `${firstName} ${lastName}`
```

こちらを日本語訳するとこんな感じです。

```
Johnという文字列をfirstNameという定数に突っ込みます
Doeという文字列をlastNameという定数に突っ込みます
firstNameとlastNameを合体させた文字列をfullNameという定数に突っ込みます
```

そして`fullName`は実際にはこのように使われています。

```react
<p>
  Hello, {fullName}
</p>
```

コードではこう書かれていますが、スクリーンショットを見ると`Hello, John Doe`と表示されています。

![Hello, John Doeと書かれた画面のスクリーンショット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/06eb28d8-01b5-3102-53a2-2ce0d755abea.png)

`{}`で囲われた`fullName`がJavaScriptとして動き、`firstName`と`lastName`の合体したもの、つまり`John Doe`としてHTMLに表れているのです。

#### ここまでのまとめ

- デザイナーがReactを触り始めるなら、まずはHTMLもどきとCSSもどきを触れれば十分
- HTMLもどきは`className`だけは暗記しておきましょう
- CSSもどきは色々な種類があるから身近にいるエンジニアに聞きましょう
- `{}`が出てきたら、今はひとまず「このカッコの中ではJavaScriptが動いているんだな」と理解できれば大丈夫

### コンポーネントを使えるようになる

HTMLもどきとCSSもどきはだいたい触れるようになったとします。

お次は、最初の方で出したメリットの「コンポーネントを組み合わせてインターフェースを作成できる」を享受できるようになりましょう。

#### とりあえず作ってみる

まずは、新しく`SomeComponent`という名前のコンポーネントを作ってみます。

```react:SomeComponent.js
function SomeComponent() {
  return (
    <p style={{ fontSize: 20, color: '#61dafb' }}>This is example component</p>
  )
}

export default SomeComponent
```

`export default SomeComponent`と書いてあるのは「よそのファイルでも`SomeComponent`を使えるようにします！」って言ってるような雰囲気で捉えてください。
そのため、これを書き忘れると他のファイルで使い回せなくなってしまいます。

例なのでそう大したことはしていませんが、フォントサイズと色とテキストを定義したコンポーネントです。
これらの組み合わせはしょっちゅう使い回す場合、毎回同じHTMLとCSSを書くのは手間ですが、Reactなら1回ここで定義すれば後は何度でも使い回せます。

先ほど例で使っていたコードを少し改変して、`SomeComponent`を利用してみましょう。

```react:App.js
import logo from './logo.svg';
import './App.css';
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link
} from "react-router-dom";
import SomeComponent from './SomeComponent'

const firstName = "John"
const lastName = "Doe"
const fullName = `${firstName} ${lastName}`

function App() {
  return (
    <Router>
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <p>
            Hello, {fullName}
          </p>
          <Switch>
            <Route path="/about">
              <About />
            </Route>
            <Route path="/users">
              <Users />
            </Route>
            <Route path="/">
              <Home />
            </Route>
          </Switch>
          <ul className="linkList">
            <li className="linkItem">
              <Link to="/" className="link">Home</Link>
            </li>
            <li className="linkItem">
              <Link to="/about" className="link">About</Link>
            </li>
            <li className="linkItem">
              <Link to="/users" className="link">Users</Link>
            </li>
          </ul>
        </header>
      </div>
    </Router>
  );
}

function Home() {
  return <h2>Home</h2>;
}

function About() {
  return (
    <>
      <h2>About</h2>
      <SomeComponent />
    </>
  );
}

function Users() {
  return (
    <>
      <h2>Users</h2>
      <SomeComponent />
    </>
  );
}

export default App;
```

※途中で`Switch`とか`Route`とか出てきていますが、無視して大丈夫です。

| Home | About | Users |
| --- | --- | --- |
| ![Homeの画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/698f9d0d-b8ce-f7bd-af66-6d76393b5474.png) | ![Aboutの画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/100773e3-133c-0319-7b0a-09c8809fb445.png) | ![Usersの画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/353f9fbd-20d1-977e-9569-012ad82ef82a.png) |

ページが3つあり、`/home`、`/about`、`/users`だとします。
そして`/about`、`/users`では`20pxで#61dafbの色のThis is example componentという文字列`、つまり`SomeComponent`を使い回したいとします。

`App.js`の最初の方で、`SomeComponent`を呼び出していますね

```react:App.js
import SomeComponent from './SomeComponent'
```

そして後の方で、繰り返し使っています。

```react:App.js
function About() {
  return (
    <>
      <h2>About</h2>
      <SomeComponent />
    </>
  );
}

function Users() {
  return (
    <>
      <h2>Users</h2>
      <SomeComponent />
    </>
  );
}
```

これにより、`/about`、`/users`では見出しの下に同じサイズと色のテキストを呼び出すことができました。

#### オーバーライドできるようにする

FigmaやSketchでは、ボタンやタブやリストなど、よく使い回すものはコンポーネント（or シンボル）として定義して適宜オーバーライドしながら使っていますよね。
もちろんReactでも可能です。

先ほど作ったSomeComponentのテキストをオーバーライドできるようにしてみましょう。

```diff_javascript
- function SomeComponent() {
+ function SomeComponent({ text }) {
    return (
-     <p style={{ fontSize: 20, color: '#61dafb' }}>This is example component</p>
+     <p style={{ fontSize: 20, color: '#61dafb' }}>This is {text} component</p>
    )
  }

  export default SomeComponent
```

まず、先ほどまでは`function SomeComponent()`だったのが`function SomeComponent({ text })`と変わっています。

これは「`text`って名前のデータを受け取ってきて使います」というニュアンスです。

そして`p`タグの中のテキストが`This is example component`から`This is {text} component`に変わっていますね。
これは「さっき受け取ってきた`text`の中身をここに表示します！」という感じです。

コンポーネントを更新できたら、`App.js`も更新します。

```diff_javascript
  function About() {
    return (
      <>
        <h2>About</h2>
-       <SomeComponent />
+       <SomeComponent text="about" />
      </>
    );
  }

  function Users() {
    return (
      <>
        <h2>Users</h2>
-       <SomeComponent />
+       <SomeComponent text="users" />
      </>
    );
  }
```

2つの`SomeComponent`の中で、それぞれ違うテキストを渡しています。
すると表示は以下のようになります。（見づらいので拡大してご覧ください :pray: ）

| About | Users |
| --- | --- |
| ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/66b60ec2-4b47-3827-8dc9-a99a4cbd7d6f.png) | ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/0129d12e-be5c-d3e9-522a-c5098122e07b.png) |

`about`の文字を渡した方は`This is about component`に、
`users`の文字を渡した方は`This is users component`になっているのがお分かりでしょうか？

もちろん文字以外にも色やサイズやレイアウトなど、色々なオーバーライドができます。
FigmaやSketchでできるオーバーライドはReactならなんでもできるので、興味を持ったら是非色々調べてみてください。

#### ここまでのまとめ

- 新規にファイルを作って「他のファイルでも使えるようにします」と宣言すればいつでも使い回せる
- 日頃FigmaやSketchで行っているようなオーバーライドもコードで実現できる

### `? :`とか`&&`とかの書き方を理解してマークアップ・スタイリングができる

このくらいの時期になるとエンジニアが書いたコードを見て、謎の記号の組み合わせをたくさん発見するのではないでしょうか？

- `? :`
- `&&`
- `||`

何が書いてあるかも良く分からないし、ググろうにもなんてググったら良いか分からないのではないでしょうか。
実はちゃんと名前があります。

- `? :` → 三項演算子
- `&&` `||` → ショートサーキット評価（短絡評価）

難しく見えますが、ちょっとしたスタイリングの出し分けや要素の出し分けを検証するときに、デザイナーもこれが理解できていると非常に便利です。

よくある使い方を記載します。

#### `? :`

よくあるコードは、だいたいこんな感じです。
`checked`は、どこかで別に宣言されていて「チェックされているか否か」を判断する役割のものだと思ってください。

```react
checked ? <OkIcon /> : <NgIcon />
```

これを日本語訳すると「チェックされてたら`OkIcon`コンポーネントを、されてなかったら`NgIcon`コンポーネントを表示する」といった具合です。

一般化すると`A ? B : C`は、`AがあればBを、なければCを出す`です。

#### `&&`

よくあるコードは、だいたいこんな感じです。
`error`はどこかで別に宣言されていて「エラーが発生しているか否か」を判断する役割のものだと思ってください。

```react
error && <ErrorMessage />
```

これを日本語訳すると「エラーがあるときだけ`ErrorMessage`を表示する」といった具合です。

一般化すると`A && B`は、`AがあればBを出す、Aがなければ何もしない`です。

#### `||`

よくあるコードは、だいたいこんな感じです。
`currentValue`はどこかで別に宣言されていて「現在の値」が入っていると思ってください。

```react
currentValue || 10
```

これを日本語訳すると「`currentValue`があればそれを、なければ10を表示する」といった具合です。

一般化すると`A || B`は、`AがあればAを出す、AがなければBを出す`です。

ここで紹介した記号の書き方を駆使して自分だけでコードを書くのは難しいかもしれません。
ですが、現状の条件分岐が分かるだけでも、HTMLもどきやCSSもどきの編集によって進められるタスクは結構あるはずです。

また、`foo && bar < 10 && baz === 'yes' && <Component />`のように複雑になっている場合もありますが、焦らず1つずつ読み解いていきましょう。

#### ここまでのまとめ

- 謎に見える記号の集まりも、ちゃんと名前もルールもある
- 若干アバウトな説明になるものの
    - `A ? B : C`は、`AがあればBを、なければCを出す`
    - `A && B`は、`AがあればBを出す、Aがなければ何もしない`
    - `A || B`は、`AがあればAを出す、AがなければBを出す`

### ダミーのStateを作って条件にあわせたマークアップ・スタイリングができる

最後です。これは結構難しく感じるかもしれませんがとても有用だと思います。

「条件をクリアしているときはAの見た目、そうでないときはBの見た目のボタンを作りたい」のようなことを考えるシーン、ありますよね？

完全な条件を実装するのは無理でも、手元でおおよその動きを検討してエンジニアに引き継ぐことはできます。

また先ほどのコードを改造して例に出します。

```react:App.js
import logo from './logo.svg';
import './App.css';
import { useState } from 'react'
import AnotherComponent from './AnotherComponent'

const firstName = "John"
const lastName = "Doe"
const fullName = `${firstName} ${lastName}`

function App() {
  const [status, setStatus] = useState(true)
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Hello, {fullName}
        </p>
        <AnotherComponent status={status} onClick={() => setStatus(!status)} />
      </header>
    </div>
  );
}

export default App;
```

コンポーネントを扱う話で出したのと同様に、`AnotherComponent`をimportしています。

```react
import AnotherComponent from './AnotherComponent'
```

その後、`return`の中で`AnotherComponent`を使用しているのですが、なんだか難しい雰囲気になっていますね。

```react
<AnotherComponent status={status} onClick={() => setStatus(!status)} />
```

このあたりの仕組みを解説します。
じつは`AnotherComponent`を呼び出すより上で、`useState`というものを呼び出しています。

```react
import { useState } from 'react'
```

これが何かを最初から理解しようとすると混乱のもとなので、今は「そういうものがあるのか」ぐらいで大丈夫です。

そして`function App()`のすぐ下で、これまた初めて見る書き方のものがあります。

```react
const [status, setStatus] = useState(true)
```

これも最初は書き方を真似ればOKです。
今は`[foo, setFoo] = useState(初期値)`という書式だけ覚えてください。

どんな名前をつけても良いですが、`foo`とつけたなら`setFoo`だし`bar`と名付けたなら`setBar`にするのが1つ。
`useState`の初期値はなんでもありですがデザイナーの範疇だと`true`か`false`かを入れておけば事足りる場合が多いです。

条件にあわせて変わるスタイルを組む、差し当たって、最初は条件をクリアしているのかいないのか、ぐらいの考え方でOKです。
デフォルトで条件をクリアしているようなものだったら`true`を、デフォルトではクリアしていなさそうだったら`false`を与えてあげてください。

そして話が若干前後しますが`AnotherComponent`においては

```react
<AnotherComponent status={status} onClick={() => setStatus(!status)} />
```

日本語訳すると「さっき定義した`status`のデータを渡す。クリックした場合は`status`の`true`と`false`を入れ替える」ようなイメージです。

じゃあ`AnotherComponent`自体のコードはどうなっているのかというと、以下です。

```react:AnotherComponent.js
import './App.css';

function AnotherComponent({ status, onClick }) {
  return (
    <button
      className={`button ${status ? 'button--ok' : 'button--ng'}`}
      onClick={onClick}
    >
      Status is {status ? 'OK' : 'NG'}
    </button>
  )
}

export default AnotherComponent
```

ひとつずつ解説すると

```react
function AnotherComponent({ status, onClick })
```

「`status`と`onClick`というデータを受け取ります」と宣言していて

```react
<button
  className={`button ${status ? 'button--ok' : 'button--ng'}`}
  onClick={onClick}
>
```

「クラス名は、いつでも`button`がついている。さっき受け取った`status`が`true`だったら`button--ok`というクラス名を、`false`だったら`button--ng`というクラス名をつける」
「ボタンをクリックしたときは、さっき受け取った`onClick`が発動する。つまり、クリックしたときに`status`の`true`と`false`を入れ替える動きをする。」

これらが全部あわさると、クリックするたびボタンのラベルと色が変わる実装ができます。

![ボタンのラベルと色が変わる様子](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/1cf49ba4-5980-2f96-ca6b-fd7c22fcd45c.gif)

条件にあわせたクラスの付け替えやアニメーション実装などができたら、エンジニアに引き継いで「実際の条件分岐」を適用してもらいましょう。

デザイナーは、スタイリングは得意だけど条件をつけたりするのが苦手。
エンジニアは、条件をつけるのは余裕だけどスタイリングは苦手。
という傾向があります。

そこを、仮の条件分岐でもデザイナーがスタイリングすることで、連携がしやすくなるはずです。

#### ここまでのまとめ

- `useState`というものを使うと、コードは少なめでも色々な状態を実現できる
- 実際のプロダクトに即していなくても、UIの状態変化を手元で再現することができる
- デザイナーだけで完成させるための手立てというよりはエンジニアと上手く協力するための知識

## まとめ

- HTMLとCSSだけじゃできないことも、Reactならできる
- ほとんどHTMLとCSSの知識で書ける箇所もある
- プラスαで覚えられれば、コードを読むときの迷いが減ったり、エンジニアとの連携がしやすくなる