- 投稿日:2020-08-04T00:58:39+09:00
React を始める
忘備録の共有です
導入
公式を参考にcliでインストールする。
npx create-react-app my-app cd my-app npm startこれで簡単にアプリの雛形が作れる。
ただ ./src 配下は階層化されているわけではないので、ここからお好みで改良していく必要がある。■公式のおすすめする指針
一つは、ルートや機能ごとにjs、cssをまとめて突っ込む方法
common/ Avatar.js Avatar.css APIUtils.js APIUtils.test.js feed/ index.js Feed.js Feed.css FeedStory.js FeedStory.test.js FeedAPI.js profile/ index.js Profile.js ProfileHeader.js ProfileHeader.css ProfileAPI.jsもう一つはファイルタイプ別に分ける方法
api/ APIUtils.js APIUtils.test.js ProfileAPI.js UserAPI.js components/ Avatar.js Avatar.css Feed.js Feed.css FeedStory.js FeedStory.test.js Profile.js ProfileHeader.js ProfileHeader.cssこのルールを突き詰めると Atomic Design になる。
■Atomic Design
流行りの設計
コンポーネントの粒度が揃って、慣れると楽そうだが慣れるまで苦労しそう
以下の様に、コンポーネントの粒度をカテゴライズして管理する
- Atoms(原子)
- 最小単位。ボタンやラベルなど、これ以上分割できないコンポーネントを指す
- Molecules(分子)
- Atoms を集めたコンポーネントを指す。例えばタイトルと写真、説明文を組み合わせたカードコンポーネントや記事の一セクションなど
- Organisms(有機体)
- Molecules を集めたコンポーネントを指す。ヘッダやフッダなど。
- Templates(テンプレート)
- ページ構造のこと。具体的に記事内容を入れたものではなく、コンポーネントの配置を定義している。ワイヤーフレーム
- Pages(ページ)
- 具体的な記事などが入ったページ本体
■どんな設計にするか(所感)
一人ならどの方法を選んでも構わないと思うが、多人数で行うプロジェクトならなるべく簡単な方法がいいと思う
特にatomic design を導入するときは、デザイナとの意思疎通もしておかないと実際にデザイナと協業しはじめた途端にトラブルが多発しそう実装
■要素のレンダー
HTML を出力するには React-DOM モジュールの render メソッドを使う。
create-react-app で生成されたアプリケーションの ./src/index.js で実際に使われている前略 ReactDOM.render( <React.StrictMode> <App /> </React.StrictMode>, document.getElementById('root') ); 後略
<App />
が独自定義した要素。忘れてはいけないのが、
/>
の部分で、React は閉じタグが無いとエラーを吐くので絶対に/>
をいれること■独自要素の定義
二種類の方法があり、要素を返すだけの関数で定義する方法と、ステートを持つクラスで定義する方法の二種類
今現在では独自ステートを持たせない方がいいとされ(使い回しが悪くなるためなどの理由)、関数で定義する方法が巷ではお勧めされている関数で定義する方法
create-react-app で生成したアプリケーションの ./src/App.js で、実際に関数で要素を定義している
前略 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 16.8 から Hook (フック)と呼ばれる新しい要素が React に追加され、関数でもステートを持たせることができる様になった
クラスで定義する方法
React.Component クラスを継承することでクラスで定義できる様になる
以下例import React from 'react' class Welcome extends React.Component { render() { return <h1>Hello World</h1> } } export default Welcome関数にしろクラスにしろ、ES6の定番でもあるが export するコンポーネントは1ファイル1つにして、ファイル名も export するコンポーネントと合わせた方がわかりやすい
また、return する要素の一番親要素は一つでないといけないルールがある
引数を取る
独自定義したタグにプロパティを定義してあげると、定義したタグの引数にkey-valueのオブジェクト形式で渡される
渡す側<App name="hoge" /> <Welcome name="hoge" />渡される側(関数)
前略 function App(props) { return ( <div className="App"> <p>Hello, {props.name}</p> 後略渡される側(クラス)
前略 class Welcome extends React.Component { render() { return <h1>Hello, {this.props.name}</h1> 後略■ステートを持たせる
従来ステートを持たせるにはクラスを使うしかなかったが、React 16.8 からフック機能が追加されたため関数でもステートを持たせることができる
redux という react のステート管理をするためのフレームワークを使う手もあるが、この記事では言及しないHook
まずは hook を使う方法
import React, {useState} from 'react'; function App(props) { const [count, setCount] = useState(0) return ( <React.Fragment> <button onClick={() => setCount(count + 1)}>CLICK ME</button> <p>{count}</p> </React.Fragment> ); } export default App;Hook で重要な関数が useState で、現在の state の値と、それを更新するための関数をペアにして返す
上記の例でいうと、count という値を定義とそれを更新するための setCount を定義し、引数の 0 で count の値を初期化しているそして button の onClick イベントのコールバックで setCount を呼んで state を更新している
これが簡単な Hook の使い方
クラス使う方法
次に従来のクラスを使う方法
import React from 'react' class Welcome extends React.Component { constructor(props) { super(props); this.state = { count: 0 } } onClick() { this.setState({ count: this.state.count + 1 }) } render() { return ( <React.Fragment> <button onClick={this.onClick.bind(this)}>CLICK ME</button> <p>{this.state.count}</p> </React.Fragment> ) } } export default Welcome早速ステートとは関係のないことだが、constructor で super(props) しているのは定型文の様なものなので、クラス構文でコンポーネントを定義して constructor を書く必要があるときは必ず書くこと
上記の例では constructor で
this.state = { count: 0 }としているところがステートを初期化しているところ。インスタンスの state プロパティにオブジェクトを渡すことで初期化できる。
上記の例で言うと、count と言う名前のステートを 0 で初期化している。ステートの更新は、setState メソッドで行う。直に更新してはいけない。
this.setState({ count: this.state.count + 1 })■CSS, 画像
import して使う。 create-react-app で作ったアプリケーションの ./src/App.js を参照
styled components
よく react と組み合わせて使われている CSS in JS のライブラリの一つ
■使い方
まずは styled-components をインストールするnpm install --save styled-componentsスタイルの定義を行う。
styled.タグ名`スタイルの定義`
で定義できるimport styled from 'styled-components' const IncrementButton = styled.div` // ここにスタイルの定義 border: 1px solid #333; background-color: #fff; cursor: pointer; display:inline-block; padding: 4px; `;定義したスタイルを使う
<IncrementButton onClick={() => setCount(count + 1)}>CLICK ME</IncrementButton>■ページ遷移
ページ遷移には react-router を使う。
インストールnpm install --save react-router-dom次に最低限必要なモジュールをインポートする
import {Link, BrowserRouter as Router, Route} from 'react-router-dom'Router の中に Link と Route を入れる
Link の to 属性にパスを定義する。この Link が a タグになる
Route には path とその path に対応する component を定義する<Router> <Link to="/">Main</Link> <Link to="/About">About</Link> <Route exact path='/' component={Main} /> <Route path='/About' component={About} /> </Router>なお、'/' の path を定義している Route に設定している exact は、パスの部分一致を否定する属性で、これがないと全てのルートがヒットしてしまう
繰り返し
配列に Dom を入れ、その配列を展開する形で繰り返しを表現できる
// 配列を用意する const ActionButtons = [] // 配列に要素を入れていく for (let i in props.data) { ActionButtons.push(<button title={props.data[i].title} path={props.data[i].path} />) } return ( <Div> // 配列変数を展開する {ActionButtons} </Div> )雑記
他に必要なことが合ったら順次追記していきます