Reactの続きです。前回はReactプロジェクトのAppコンポーネントを打ち替えてみました。今回は複数のクラスコンポーネントを作って、入れ子関係にしたりファイル分割してエクスポート、インポートする構造を作ります。それではいきましょう!
【目次】
※参考:【React】ReactプロジェクトのAppコンポーネントを書き換えてみる - クモのようにコツコツと
※Reactでやってみたことまとめ
qiita.com
Appコンポーネントをクラスにする
Appクラスを作成
今回も掌田さんの「React.js & Next.js入門」を参考に進める。
- 作者:掌田津耶乃
- 発売日: 2019/08/30
- メディア: Kindle版
前回のAppコンポーネント(App.js)のコードを改造してクラスを作る。
前回のJSX部分はApp()
関数だった
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> ); }
詳細は前回の記事を参照。
※参考:【React】ReactプロジェクトのAppコンポーネントを書き換えてみる - クモのようにコツコツと
これをクラスにする。
class App extends React.Component { constructor(props) { super(); this.title = props.title; this.message = props.message; } render() { return <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <h1>{this.title}</h1> <p>{this.message}</p> </header> </div> } }
App
クラスでReact.Component
を継承constructor()
でコンストラクタを設定。引数はprops
- コンストラクタの中で
this.title
、this.message
を定義 render()
でレンダリングするJSXを設定h1
タグでthis.title
、p
タグでthis.message
を読み込む
クラスコンポーネントの詳細はこちらを参照
※参考:【React】クラスを使ったコンポーネントの書き方(React.Component、render()、super()) - クモのようにコツコツと
※参考:【React】クラスコンポーネントで属性を設定する - クモのようにコツコツと
App.js全体はこうなる。
import React from 'react'; import logo from './img/prof.jpg'; import './App.css'; class App extends React.Component { constructor(props) { super(); this.imgSrc = props.imgSrc; this.title = props.title; this.message = props.message; } render() { return <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <h1>{this.title}</h1> <p>{this.message}</p> </header> </div> } } export default App;
index.jsの値を入れる
次にindex.jsのApp
コンポーネントでクラスに読み込ませたいテキストの値を設定する。
前回はApp
コンポーネントはタグ名だけだったが
<App />
※参考:【React】ReactプロジェクトのAppコンポーネントを書き換えてみる - クモのようにコツコツと
今回はtitle
属性とmessage
属性でテキストを設定する。
<App title="クモのようにコツコツと" message="Reactコンポーネントもコツコツと!" />
index.js全体はこうなる。
import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import * as serviceWorker from './serviceWorker'; ReactDOM.render( <React.StrictMode> <App title="クモのようにコツコツと" message="Reactコンポーネントもコツコツと!" /> </React.StrictMode>, document.getElementById('root') ); serviceWorker.unregister();
Reactプロジェクトを起動
この状態でReactプロジェクトを起動してみる。ターミナルでフォルダに移動する。
cd /(フォルダ)/react_app
プロジェクトを起動!
npm start
ブラウザでローカルホストのページが立ち上がる!
http://localhost:3000/
こんなんでました! 見た目は前回とあまり変わらないんだけどページに表示されている「クモのようにコツコツと」「Reactコンポーネントもコツコツと!」はコンポーネントの属性から読み込まれたテキスト!
複数のコンポーネントを入れ子構造にしてみる
Imgクラス作成
コンポーネントは複数作って入れ子構造にできる。クルクル回る画像部分を別のコンポーネントにしてみる。
まずImg
クラスを作成する。
class Img extends React.Component { align = 'left'; style = {}; constructor(props) { super(); this.align = props.align; this.style = { textAlign: this.align }; } render() { return <img src={logo} className="App-logo" alt="logo" style={this.style} /> } }
- グローバル変数
align
を設定。初期値はleft
- グローバル変数
style
を設定。初期値は空の連想配列 - コンストラクタで
this.align
とthis.style
を設定 this.style
の中のtextAlign
はthis.align
を読み込む- レンダリングするJSXを設定
img
タグの中でstyle
属性を設定。中身はthis.style
Appクラウの中にImgコンポーネントを配置
次にApp
クラスの中でImg
コンポーネントを配置する
class App extends React.Component { // 中略 render() { return <div className="App"> <header className="App-header"> <div className="App-images"> <Img align="left" /> <Img align="center" /> <Img align="rignt" /> </div> <h1>{this.title}</h1> <p>{this.message}</p> </header> </div> } }
.App-images
タグを追加し、その中にImg
コンポーネントを3つ配置Img
コンポーネントの中のalign
属性はそれぞれleft
、center
、rignt
これで3つの画像のtext-align
が左寄せ、中央寄せ、右寄せになるはず。
ブラウザを確認するとドン! 画像が3つに増えてクルクルと回っているw
App.js全体
App.js全体はこうなった。
import React from 'react'; import logo from './img/prof.jpg'; import './App.css'; class App extends React.Component { constructor(props) { super(); this.title = props.title; this.message = props.message; } render() { return <div className="App"> <header className="App-header"> <div className="App-images"> <Img align="left" /> <Img align="center" /> <Img align="rignt" /> </div> <h1>{this.title}</h1> <p>{this.message}</p> </header> </div> } } class Img extends React.Component { align = 'left'; style = {}; constructor(props) { super(); this.align = props.align; this.style = { textAlign: this.align }; } render() { return <img src={logo} className="App-logo" alt="logo" style={this.style} /> } } export default App;
複数コンポーネントを別ファイルに切り分ける
ImgクラスをImg.jsに分離する
コンポーネントは別ファイルに切り分けて読み込みこともできる。やってみる。
「src」フォルダに「Img.js」を作成する。
import React from 'react'; import logo from './img/prof.jpg'; import './App.css'; class Img extends React.Component { align = 'left'; style = {}; constructor(props) { super(); this.align = props.align; this.style = { textAlign: this.align }; } render() { return <img src={logo} className="App-logo" alt="logo" style={this.style} /> } } export default Img;
- 冒頭で
react
とprof.jpg
とApp.css
をインポート Img
クラスをこちらに持ってくる- 最後に
Img
コンポーネントをエクスポート
App.jsでImgコンポーネントを読み込む
次に「App.js」を修正する。
import React from 'react'; import Img from './Img'; import './App.css'; class App extends React.Component { constructor(props) { super(); this.title = props.title; this.message = props.message; } render() { return <div className="App"> <header className="App-header"> <div className="App-images"> <Img align="left" /> <Img align="center" /> <Img align="rignt" /> </div> <h1>{this.title}</h1> <p>{this.message}</p> </header> </div> } } export default App;
- 冒頭で
Img
コンポーネントをインポート(prof.jpg
は削除) Img
コンポーネント部分は削除し、App
コンポーネントのみ残す
2つのコンポーネントのインポート、エクスポートの方向が明確になった!
なお、index.jsは変更していないのでApp
コンポーネントを読み込んでいるだけ。
ブラウザ確認すると… 先ほどと変わらない挙動!
最後に
ということで、クラスコンポーネントを作成し、入れ子構造にしたりファイルを分割してインポート、エクスポートする状態にしました。だんだんとコンポーネントを部品のように構成して作っていくイメージが湧いてきました!
次回は「ステート」機能による値の保管に入ります。それではまた!
※Reactでやってみたことまとめ
qiita.com