Reactの基礎
JSXについて
React で JSX を使うことは必須ではありません。
しかし、JSX を使うと React 要素をより簡便な形式で作成できます。
JSX は JavaScript の拡張言語であり、HTMLライクな記述 + JavaScriptの構文が使える。
結局、JSXはJavaScriptというプログラミング言語とHTMLというドキュメント言語を2つ掛け合わせて使えるようにしたもの。
JSX記法のルールについて
import React from "react";
import ReacrDom from "react-dom";
const App () => {
return (
<>
<h1>こんにちは!</h1>
<p>お元気ですか?</p>
</>
);
};
ReactDom.render(<App />, document.getElementById("root"));
コンポーネント、Props、Stateについて
コンポーネント・・・画面要素の1単位。1つのWEBページの全てを表示させることもできるし、テキストボックスなどの一部を表示させることもできる。
Props・・・コンポーネントに渡される引数みたいなもの。
State・・・各コンポーネントが持つ状態。stateが変更されると再レンダリングされる。
コンポーネントの使い方
return内にHTMLタグを長々と記載していくと見づらくなっていくので、いろんなファイルに分けてコンポーネントとして管理していく。
下記では、コンポーネント化したApp.jsをindex.jsでインポートして使用している。
index.js:コンポーネント化したApp.jsをimportして使用している。
App.js:画面のレンダリング部分(return内のHTMLタグ)をコンポーネント化している。
import React from "react";
import ReacrDom from "react-dom";
import App from "./App";//App.jsをimportして使えるようにしている。
ReactDom.render(<App />, document.getElementById("root"));
import React from "react";
const App = () => {
return (
<>
<h1>こんにちは!</h1>
<p>お元気ですか?</p>
</>
);
};
export default App;
//exportすることによってこのファイル(App.jsx)を他のファイルで使用することができる。
ファイル名は.jsxでも.jsでも問題ないが、コンポーネント化したファイルは.jsxにしたほうが良い。
コンポーネントの命名規則について
先頭が大文字で始まり、単語の区切りを大文字とする変数名の付け方を「パスカルケース」と呼びます。
Reactのコンポーネントはこのパスカルケースで命名しましょう!
Reactでのイベントやstyleの扱い方
import React from "react";
const App = () => {
const OnclickButton = () => alert();
const contentstyle = {
color: "blue"
fontSize: "18px"
};
return (
<>
<h1 style={{ color: "red"}}>こんにちは!</h1>
<p style={contentStyle}>お元気ですか?</p>
<button onClick={onClickButton}>ボタン</button>
</>
);
};
export default App;
<h1></h1>タグは、直接オブジェクトをタグ内に記載している(タグに埋め込む形)
<p></p>タグは、オブジェクトの変数を定義して、CSSのプロパティの内容をスタイルに反映している。
ボタンをクリックするとonClickイベントが発生、関数{onClickbutton}が呼び出されてアラートが表示される。
Propsについて
//App.js(パターン1)
import React from "react";
import ColofulMessage from "./components/ColorfulMessage-pattern1";
const App = () => {
const OnclickButton = () => alert();
return (
<>
<ColofulMessage color="pink" message="元気です"/>
</>
);
};
export default App;
ColofulMessage.jsxのpropsにcolorとmessageを渡している。
colorとmessageは、オブジェクトのプロパティとしてpropsに渡している。
import React from "react";
//console.log(props)
//コンソールログで出力するとpropsの中身(オブジェクトのプロパティ)colorとMessageが表示される。
const App = () => {
const ColofulMessage = (props) => {
const contentStyle = {
color: props.color,
fontSize: "18px"
};
return <p style={contentStyle}>{props.message}</p>;
};
export default ColofulMessage;
App-pattern1.jsxのcolor="pink" message="元気です"が、
ColorfulMessage-pattern1.jsxのprops.colorとprops.message部分に反映されて
ブラウザ画面に出力される。
//App.js(パターン1)
import React from "react";
import ColofulMessage from "./components/ColorfulMessage-pattern2";
const App = () => {
const OnclickButton = () => alert();
return (
<>
<ColofulMessage color="pink">元気です</ColofulMessage>
</>
);
};
export default App;
パターン1:<ColofulMessage color="pink" message="元気です"/>
パターン2:<ColofulMessage color="pink">元気です</ColofulMessage>
パターン2ではメッセージ部分を<ColofulMessage></ColofulMessage>のタグで囲っている。
タグで囲った内容は、Childrenの要素に入る。
import React from "react";
const { color, children } = props;
const App = () => {
const ColofulMessage = (props) => {
const contentStyle = {
color: color,
fontSize: "18px"
};
return <p style={contentStyle}>{children}</p>;
};
export default ColofulMessage;
const { color, children } = props;部分では、分割代入を使いオブジェクトpropsのcolorとchildrenの要素を抜き出す。
オブジェクトのプロパティ名(color)と値に指定する変数名(color)が同じ場合propsを省略できる。
つまり、分割代入で抜き出すことによってパターン1のようにcolor: props.color, → color: color, に書き換えることが可能になる。
return <p style={contentStyle}>{children}</p>;部分では、
分割代入で抜き出すことによってprops.childrenではなくchildrenとして値を使える。
また、分割代入しなかった場合、タグで囲った中身をprops.childrenとして渡すこともできる。
Stateについて(useState)
import React, { useState } from "react";
//useStateを使う場合、importする構文が少し変わる
import ColofulMessage from "./components/ColorfulMessage-pattern2";
const App = () => {
const onClickCountUp = () => {
setNum(num + 1);
//説明1
};
const [num, setNum] = useState(0);
//説明2
return
<>
<h1 style={{ color: "red"}}>カウントアップ機能</h1>
<button onClick={onClickCountUp}>カウントアップ!</button>
<p>{num}</p>
//説明3
</>
);
};
export default App;
ボタンをクリックすると、数字がカウントアップしていく機能を実装。
また、ColorfulMessage-pattern2をインポートしている。(特に問題ないのでそのまま使用)
再レンダリングの副作用とuseEffectについて
import React, { useState } from "react";
import ColofulMessage from "./components/ColorfulMessage-pattern3";
const App = () => {
console.log("AppRendering.jsxレンダリング確認");
//説明1
const [num, setNum] = useState(0);
const [helloFlag, setHelloFlag] = useState(true);
//説明2
const onClickCountUp = () => {
setNum(num + 1);
};
const onSwitchHelloFlag = () => {
setHelloFlag(!helloFlag);
};
return (
<>
<ColofulMessage color="blue">カウントアップ機能</ColofulMessage>
<button onClick={onClickCountUp}>カウントアップ!</button>
<p>{num}</p>
<br />
<button onClick={onSwitchHelloFlag}>on/off</button>
//説明3
{helloFlag && <p>hello!</p>}
//説明4
</>
);
};
export default App;
import React from "react";
const ColofulMessage = (props) => {
console.log("ColorfulMessage-pattern3.jsxレンダリング確認");
//説明5
const { color, children } = props;
const contentStyle = {
color,
fontSize: "18px"
};
return <p style={contentStyle}>{children}</p>;
};
export default ColofulMessage;
import React, { useState } from "react";
import ColofulMessage from "./components/ColorfulMessage-pattern3";
const App = () => {
console.log("AppRendering-error.jsxレンダリング確認");
const [num, setNum] = useState(0);
const [helloFlag, setHelloFlag] = useState(true);
const onClickCountUp = () => {
setNum(num + 1);
};
const onSwitchHelloFlag = () => {
setHelloFlag(!helloFlag);
};
if (num % 3 === 0) {
setHelloFlag(true);
} else {
setHelloFlag(false);
//説明1
}
return (
<>
<ColofulMessage color="blue">カウントアップ機能</ColofulMessage>
<button onClick={onClickCountUp}>カウントアップ!</button>
<p>{num}</p>
<br />
<button onClick={onSwitchHelloFlag}>on/off</button>
{helloFlag && <p>hello!</p>}
</>
);
};
export default App;
import React, { useState } from "react";
import ColofulMessage from "./components/ColorfulMessage-pattern3";
const App = () => {
console.log("AppRendering-error-fix.jsxレンダリング確認");
const [num, setNum] = useState(0);
const [helloFlag, setHelloFlag] = useState(false);
const onClickCountUp = () => {
setNum(num + 1);
};
const onSwitchHelloFlag = () => {
setHelloFlag(!helloFlag);
};
if (num > 0) {
if (num % 3 === 0) {
helloFlag || setHelloFlag(true);
//説明1
} else {
helloFlag && setHelloFlag(false);
//説明2
}
}
return (
<>
<ColofulMessage color="blue">カウントアップ機能</ColofulMessage>
<button onClick={onClickCountUp}>カウントアップ!</button>
<p>{num}</p>
<br />
<button onClick={onSwitchHelloFlag}>on/off</button>
{helloFlag && <p>hello!</p>}
</>
);
};
export default App;
import React, { useEffect, useState } from "react";
//説明1
import ColofulMessage from "./components/ColorfulMessage-pattern3";
const App = () => {
console.log("AppRendering-useEffect.jsxレンダリング確認");
const [num, setNum] = useState(0);
const [helloFlag, setHelloFlag] = useState(false);
const onClickCountUp = () => {
setNum(num + 1);
};
const onSwitchHelloFlag = () => {
setHelloFlag(!helloFlag);
};
useEffec(() => {
console.log("useEffect確認");
//説明2
if (num > 0) {
if (num % 3 === 0) {
helloFlag || setHelloFlag(true);
} else {
helloFlag && setHelloFlag(false);
}
}
}, [num]);
//説明3
return (
<>
<ColofulMessage color="blue">カウントアップ機能</ColofulMessage>
<button onClick={onClickCountUp}>カウントアップ!</button>
<p>{num}</p>
<br />
<button onClick={onSwitchHelloFlag}>on/off</button>
{helloFlag && <p>hello!</p>}
</>
);
};
export default App;
静的構文解析ツールのESLintで下記エラーが出た場合の対処方
/*eslint react-hooks/exhaustive-deps: off*/
//説明1
import React, { useEffect, useState } from "react";
import ColofulMessage from "./components/ColorfulMessage-pattern3";
const App = () => {
console.log("AppRendering-useEffect.jsxレンダリング確認");
const [num, setNum] = useState(0);
const [helloFlag, setHelloFlag] = useState(false);
const onClickCountUp = () => {
setNum(num + 1);
};
const onSwitchHelloFlag = () => {
setHelloFlag(!helloFlag);
};
useEffec(() => {
console.log("useEffect確認");
if (num > 0) {
if (num % 3 === 0) {
helloFlag || setHelloFlag(true);
} else {
helloFlag && setHelloFlag(false);
}
}
//eslint-disable-next-line
//説明2
}, [num]);
return (
<>
<ColofulMessage color="blue">カウントアップ機能</ColofulMessage>
<button onClick={onClickCountUp}>カウントアップ!</button>
<p>{num}</p>
<br />
<button onClick={onSwitchHelloFlag}>on/off</button>
{helloFlag && <p>hello!</p>}
</>
);
};
export default App;
default exportとexport
//ファイルをexportする方
import React from "react";
export const ColofulMessage = (props) => {
//説明1
console.log("ColorfulMessage-not-default.jsxレンダリング確認");
const { color, children } = props;
const contentStyle = {
color,
fontSize: "18px"
};
return <p style={contentStyle}>{children}</p>;
};
//export default ColorfulMessage-not-default;
//説明2
//ファイルをimportする方
import React, { useState } from "react";
import {ColofulMessage} from "./components/ColorfulMessage-not-default";
//説明1
const App = () => {
console.log("App.jsレンダリング確認");
const [num, setNum] = useState(0);
const [helloFlag, setHelloFlag] = useState(true);
const onClickCountUp = () => {
setNum(num + 1);
};
------以下のコードは省略------
クラスコンポーネントは必要なのか?
結論から言うと、新規のプロジェクトはクラスコンポーネントは不要!
もともと、クラスコンポーネントと関数コンポーネントは、明確な使い分けがあった。
stateが使える(管理できる)のはクラスコンポーネントだけで
関数コンポーネントはpropsを受け取ってなにかするという認識だったため、
stateを含むのならクラスコンポーネント、
それ以外なら関数コンポーネントで作成しましょうといった感じが王道のreactの使い方だった。
しかし、react hooksの登場で関数コンポーネントでもstateが使えるようになった。
クラスコンポーネントの勉強を頑張って勉強する必要はないが、古いプロジェクトにあたった場合、クラスコンポーネントに触れる可能性はある。
Discussion