修羅の国からえんじにあ

主に Ruby on Rails の実験を書き留めていく予定

RailsのWebpackでReactに挑戦 (2) コンポーネント

rassy.hatenablog.jp

続きです。

前回は、とりあえず起動に成功したので、何を変えたらどうなるのか・・・的な考察をやってみたいと思います。

さて、コンポーネントとはなんぞ?

まずは、Reactを構成するコンポーネントについて考えてみます。

まずは、余分な情報を除きたかったので、サンプルをコピーしつつ、最初の定義らしいものを表示させるようにしてみます。

import React from 'react'
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types'

const Hello = props => (
  <div>Hello {props.name}!</div>
)

const Hoge = () => (
  <li>hoge</li>
)

Hello.defaultProps = {
  name: 'David'
}

Hello.propTypes = {
  name: PropTypes.string
}

document.addEventListener('DOMContentLoaded', () => {
  ReactDOM.render(
    <Hello name="React" />,
    document.body.appendChild(document.createElement('div')),
  )
})

document.addEventListener('DOMContentLoaded', () => {
  ReactDOM.render(
    <Hoge/>,
    document.body.appendChild(document.createElement('ul')),
  )
})

このようにサンプルを書き換えてみました。

追記箇所としては、

const Hoge = () => (
  <li>hoge</li>
)


document.addEventListener('DOMContentLoaded', () => {
  ReactDOM.render(
    <Hoge/>,
    document.body.appendChild(document.createElement('ul')),
  )
})

この部分となります。

まずは最初のステップですので、ステータスやバリデーションらしきモノを排除してプレーンな定義としています。

しらべてみると、ここの

const Hoge = () => (
  <li>hoge</li>
)

が、コンポーネントとなり、やっているのは、アロー関数を使った定義のようです。

よく書籍なんかで出ている React.createClass の記法(すでに非推奨)を今風に書き換えたものらしい。

個人的には、

const Hoge = () => {
  return(
    <li>hoge</li>
  )
}

このぐらいでも良いけど、(実際動く)が、折角新しい事を覚えるので、シンプルに覚えたいですね。

さて、結果ですが・・・

f:id:kimny7544:20171128030052p:plain

無事にリスト表示されています。

f:id:kimny7544:20171128030356p:plain

デベロッパーツールでもこの通り。

しかし、ソース表示だと、

f:id:kimny7544:20171128030933p:plain

ファイル呼んでるだけ・・・まぁ、そらそうですよねw

ちなみにですが、

const Hoge = (props) => (
  <li>hoge</li>
)

このようにやってもエラー出ませんし、

const Hoge = (props) => (
  <li>hoge{props.name}</li>
)

こうしてもエラーになりません。

render側で、

document.addEventListener('DOMContentLoaded', () => {
  ReactDOM.render(
    <Hoge name="hoge" />,
    document.body.appendChild(document.createElement('ul')),
  )
})

このように、 <Hoge/>,name を付け加えると値が反映されます。

f:id:kimny7544:20171128032257p:plain

狙い通りきちんと、fugafuga したようです。

さて、ここで疑問なのですが、

const Hoge = props => (
  <li>hoge{props.fuga}</li>
)

document.addEventListener('DOMContentLoaded', () => {
  ReactDOM.render(
    <Hoge huga="hoge" />,
    document.body.appendChild(document.createElement('ul')),
  )
})

このように、 namefuga と適当に変えてみるとどうなるのか試したらどうなるか。

f:id:kimny7544:20171128030052p:plain

はい。今度は残念な結果となりました。

これはアローの引数が、何か固定のプロパティ名を複数?持っているという話になりますね。

詳しく調べるのは後回しとしまして・・・次に、 props は通常何でも良いと考えていたのですが、プロパテイをすでに持っているとなるとちょっと怖いので、念のため試しておきましょう。

const Hoge = fugafuga => (
  <li>hoge{fugafuga.name}</li>
)

document.addEventListener('DOMContentLoaded', () => {
  ReactDOM.render(
    <Hoge name="hoge" />,
    document.body.appendChild(document.createElement('ul')),
  )
})

このように変更すると・・・

f:id:kimny7544:20171128032257p:plain

あ・・・これは大丈夫のようです。

ということはやはり、ただのブロック変数という事ですね。

しかし、他に用途がないのであれが、ネーミング的には props でしっくり来るのでそのままで良い気がしますね。

という事で、最低限書いておくと良い記述としては、

const Hoge = 変数名 => (
  <div>HTMLが普通に書ける{ ブロックで変数のプロパティが展開出来る }</div>
)

こんな感じかと思われます。

さて、ここで気を良くして、「折角リストなんだから複数入れてみよう。」という話になりますよね。

試してみます。

const Hoge = props => (
  <li>hoge</li>
  <li>hoge</li>
  <li>hoge</li>
)

はい・・ではどうなるか・・。

f:id:kimny7544:20171128035352p:plain

結果:惨敗

駄目みたいですね。というかエラー画面が無駄にカッコいいんですけど・・・。

エラー画面で折れたので、今日はここまでです。

次回は、リスト表示などのくりかえし要素を作る方法を実験する予定です。