Reactはユーザインターフェイス(UI)を作成することに特化したJavascriptのパッケージです。
環境構築
Windowsでnode.jsをインストールしておきました。エディターはvscodeでvscode上でコマンドプロンプトを動かして操作します。詳しくは以下の記事をご覧ください。
ターミナルで
npm install -g create-react-app
create-react-app tutorial
と入力してreactが使えるディレクトリtutorialを作り、この中でデモをやっていきます。
以下の記事の通りにやれば、補間機能も設定できます。
実行
ターミナルで
npm start
と打てば、勝手にブラウザが開いてlocalhostで出力されます。また、コードを書き替えたとき、普通はctrl+cで中断してから再起動する必要がありますが、Reactにはホットリローディングという機能があって、書き換えたコードを保存すると、自動的にブラウザの方にも変更が反映されます。
コンソールでの確認
console.log('comment');
はブラウザのコンソールに出力されます。例えばedgeだとctrl+shift+Iで開発者ツールを開くとコンソールのタブがあるのでそこから確認できます。
Hello World!
まずは、Hello World!と画面に表示してみます。tutorial/srcの中に、index.jsというファイルがあると思います。これがブラウザへの出力のソースコードです。
これを以下のように書き換えます。
import React from 'react';
import ReactDOM from 'react-dom/client';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<h1>Hello world!</h1>
);
すると、ブラウザには次の画面が出力されます。
実はtutorial/public/index.htmlに
:
:
<div id="root"></div>
:
:
という記述があり、index.js内の
const root = ReactDOM.createRoot(document.getElementById('root'));
によって、index.html内のこの部分とindex.jsのrootというオブジェクトが対応付けられています。
そしてindex.jsの2行目の
root.render(
<h1>Hello world!</h1>
);
で、引数に書かれた内容が
<div id="root"></div>
に反映されます。
箇条書きの表示
import React from 'react';
import ReactDOM from 'react-dom/client';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<ul>
<li>item 1</li>
<li>item 2</li>
</ul>
);
コンポーネント化
長いhtmlファイルを平文で書いていくと、とても煩雑になります。そこで中身を外に出して他のファイルから読み込む形にすることで、見た目をスッキリさせることができます。また、複数人で分担するときにもコードを分割して作業できた方がやりやすいですね。
まず、外に出すやり方から見ていきましょう。
例えば次のように表示する中身を外に出すことができます。(変数にhtmlファイルの中身を渡すのは少し違和感があるかもしれませんが...)
import React from 'react';
import ReactDOM from 'react-dom/client';
const page = <div>
<h1 className='header'>This is JSX</h1>
<p>This is a paragraph</p>
</div>
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(page);
出力結果:
外に出した中身をJSXと言い、これが外に出した中身のコンポーネントです。JSXの中身が複数ある場合は必ず
<div> </div>
で囲んでひとつにまとめてください。
画像の表示
画像はtutorial/public/logo192.pngをtutorial/src/react-logo.pngにコピーしたものを使いました。
import React from 'react';
import ReactDOM from 'react-dom/client';
import logo from "./react-logo.png"//画像の情報の読み込み
const page = (
<div>
<img src={logo} className="App-logo" alt="logo" />//画像の表示
<h1>Fun fact about React</h1>
</div>
);
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(page);
出力結果:
関数としてのコンポーネント
通常、JSXオブジェクトは直接グローバル変数で定義せず、関数の返り値として取得します。なお、このとき関数名は大文字から始めなければいけません。
import React from 'react';
import ReactDOM from 'react-dom/client';
import logo from "./react-logo.png"
function Logopage(){
return (
<div>
<img src={logo} className="App-logo" alt="logo" />
<h1>Fun fact about React</h1>
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById('root'));
//<関数名/>で関数の返り値のJSXを反映させる
root.render(
<Logopage/>
);
複数のコンポーネントに分割
import React from 'react';
import ReactDOM from 'react-dom/client';
import logo from "./react-logo.png"
function Header(){
return(
<header>
<img src={logo} className="App-logo" alt="logo" />
</header>
);
};
function MainContent(){
return (
<div>
<h1>Reasons I'm excited to learn React</h1>
<ol>
<li>It's a popular library, so I'll be
able to fit in with the cool kids!</li>
<li>I'm more likely to get a job as a developer
if I know React</li>
</ol>
</div>
);
};
function Logopage(){
return (
<div>
<Header/>
<MainContent/>
</div>
);
};
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Logopage/>);
ファイル分割
先ほどのHello WorldのコードでHello World!を表示する部分を他のApp.jsというファイルにファイルに分割したいと思います。
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';//App.jsから関数Appを読み込む
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<App />//Appの中身を反映したコンポーネント
);
import React from 'react';
function App() {
return(
<div className="App">
<h1>Hello World!</h1>
</div>
);
};
export default App;//関数Appを他のファイルから読み込めるようにする。
これで先ほどと同じようにHello World!が出力されます。ちなみにindex.jsを
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>//追加部分
<App />
</React.StrictMode>//追加部分
);
とすると、ささいなバグや不具合でもエラーにとして検出されるようになります。index.jsはこれを使って、基本的にはApp.jsの中身をいじって色々な操作をすることになります。
CSSファイルの読み込み
classNameのところに自分で作った描画スタイルを設定することができます。その設定内容を書いたファイルがCSSファイルです。
import React from 'react';
import ReactDOM from 'react-dom/client';
import logo from './react-logo.png'
import './style.css'//cssファイルの読み込み
function Header(){
return(
<header>
<img src={logo} className="nav-logo" alt="logo" />//styel.cssファイルで設定したものを使った
<ul className='nav-items'>//styel.cssファイルで設定したものを使った
<li>Pricing</li>
<li>about</li>
<li>list</li>
</ul>
</header>
);
};
function MainContent(){
return (
<div>
<h1>Reasons I'm excited to learn React</h1>
<ol>
<li>It's a popular library, so I'll be
able to fit in with the cool kids!</li>
<li>I'm more likely to get a job as a developer
if I know React</li>
</ol>
</div>
);
};
function Logopage(){
return (
<div>
<Header/>
<MainContent/>
</div>
);
};
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Logopage/>);
.nav{
display: flex;
justify-content: space-between;
align-items: center;
}
.nav-logo{
width: 60 px;
}
.nav-items{
list-style: none;
display: flex;
}
.nav-items > li{
padding: 10px;
}