レビュー
冬休み期間中のスキルアップの一環として、
Amazonでレビューの高かったこの本を買いました。
Reactの入門書としては良書だと思います。
入門書なので、挫折することはまずないと思います。
CSS、コンポーネント間の値の受け渡し、Hooks、グローバルstate、TypeScriptに一通り触れられているので、
技術記事をある程度読めるようになるのではないでしょうか。
この本だけで現場で開発できるようになるかというと、
初心者がいきなりこの本で入門しただけでは難しいでしょう。
でも、Vue.jsやAngulerなど他のSPAフレームワークを使っていた人なら、
この本でサラッと押さえれば後は調べながら開発できるかもしれません。
1日で全体を写経できると思います。
優しく丁寧に描かれているので、挫折せず気持ちよく終われると思います。
入門書はそれが大事ですね。
ファイル名
コンポーネントファイルは.jsx拡張子で統一するのがベター。
・一目でreactのコンポーネントであることがわかる。
・エディターの補完機能が働く。
イベント
<button onClick={関数名}>ボタン</button>
このように、各HTMLタグの属性にイベントを定義する。
CSS
HTMLタグに直接当てる(inlineスタイル)
<h1 style={{color:"red"}}>こんにちは!</h1>
変数を挟んで当てることもできる。
const contentStyle = {
color: "blue",
fontSize: "20px",
}
return (
<>
<p style={contentStyle}>お元気ですか?</p>
</>
);
font-sizeではなくfontSizeである。
JavaScriptのオブジェクトのプロパティ名はキャメルケースだからである。
inlineスタイルはHTMLが読みづらくなるため、あまり使わない方が良い。
CSS Modules
- 従来のWeb開発と同じく、CSSとJSXを分けて書く。
- デザイナーとの協業がしやすい。
- コンポーネント毎にCSSを書いていく。
使用準備
$ yarn add node-sass
CSS
.title {
color: #aaa,
}
.button {
background-color: #ddd;
}
コンポーネント
import classes from "./CssModules.module.scss"
export const CssModules = () => {
return (
<>
<p className={classes.title}>CSS Modulesです</p>
<button className={classes.button}>ボタン</button>
</>
)
}
Styled JSX(CSS in JSの1つ)
- コンポーネント内にCSSを書いていく。
- あまり積極的に採用されないが、Next.jsには標準で組み込まれている。
- SCSS記法は使用できない。
使用準備
$ yarn add styled-jsx
コンポーネント
export const StyledJsx = () => {
return (
<>
<p className="title">StyledJsxです</p>
<button className="button">ボタン</button>
<style jsx>{`
.title {
color: red;
}
.button {
background-color: green;
}
`}</style>
</>
)
}
Styled Components(CSS in JSの1つ)
- 採用しているプロジェクトは多い。
- SCSS記法が使用できる。
使用準備
$ yarn add styled-components
コンポーネント
import styled from "styled-components";
export const StyledComponents = () => {
return (
<>
<STitle>StyledComponents</STitle>
<SButton>ボタン</SButton>
</>
)
}
const STitle = styled.p`
color: blue;
`
const SButton = styled.button`
background-color: green;
`
Emotion (CSS in JSの1つ)
- 採用しているプロジェクトは多い。
- Inline Styles,Styled JSX,styled componentsのどの書き方もできる。
- 方針が決まってないときにどれでも対応できる。
- 方針を決めておかないとばらつきが生じ、保守性が下がる。
使用準備
$ yarn add @emotion/react @emotion/styled
コンポーネント
/** @jsxImportSource @emotion/react */
import { css } from "@emotion/react";
import styled from "@emotion/styled"
export const Emotion = () => {
// scssの書き方がそのまま可能な書き方
const containerStyle = css`
border: solid 1px #aaa;
border-radius: 20px;
padding: 8px;
margin: 8px;
`;
// インラインスタイルの書き方
const titleStyle = css({
margin: 0,
color: "red"
});
// styled-componentsの書き方
const SButton = styled.button`
background-color: black;
`
return (
<div css={containerStyle}>
<p css={titleStyle}>Emotionです</p>
<SButton>ボタン</SButton>
</div>
)
}
Tailwind CSS
- 世界中でユーザー数の多いCSSフレームワーク。
- HTMLやVue.jsにも適用できる。
使用準備
https://tailwindcss.com/docs/guides/create-react-app
$ yarn add -D tailwindcss@npm:@tailwindcss/postcss7-compat postcss@^7 autoprefixer@^9
$ yarn add @craco/craco
$ ./node_modules/.bin/tailwindcss init
設定ファイル1
設定ファイル2
コンポーネント
子コンポーネントへの値の渡し方
2つの方法を押さえておこう。
propsを使用する
import {Child} from "./Child";
export const Parent = () => {
return (
<>
私は親です。
<Child name={"二郎"}></Child>
</>
)
}
export const Child = (props) => {
const {name} = props;
return (
<>
私は子供で、名前は{name}です。
</>
)
}
childrenを使用する
import {ChildB} from "./ChildB";
export const ParentB = () => {
return (
<>
<ChildB >コンテンツをまるっと渡せます</ChildB>
</>
)
}
export const ChildB = (props) => {
const {children} = props;
return (
<>
受け取ったコンテンツは{children}です。
</>
)
}
props vs children
childrenは複雑はHTMLタグをそのまま渡すことができる。
また、親側(渡す方)もHTMLタグそのまま書けることで、何をやっているか若いりやすいため、childrenを使うシーンが多い。
childrenはデフォルトの機能であり、渡す引数を1つ減らせるため、コンテンツを渡す場合はchildrenを推奨する。
状態管理(useState)
Vue.jsとReactの違い
Vue.jsでいうところのdataは、ReactではuseStateを使って実現する。useState関数はReact Hooksの1つである。
...
data: function() {
return {
num: 0,
}
}
useState関数
import { useState } from "react";
...
const [num, setNum] = useState(0);
setNum((prev) => prev +1 );
...
<p>{num}</p>
上記のように、状態管理する変数をuseState関数の戻り値として宣言する。
stateが変更されたら、コンポーネントは再度評価され(最初から処理が行われ)、return内容に差分がある場合は、再度レンダリングされる。
useEffectで特定の状態が変わった時だけ処理を実行させる
useEffetct関数はReact Hooksの1つである。
React Hooks(フック)とは何か?
フックとは何? フックとは React の機能に「接続 (hook into)」するための特別な関数です。例えば
https://ja.reactjs.org/docs/hooks-state.html#whats-a-hookuseState
によって React の state の機能を関数コンポーネントに追加できます。他のフックについても後で学びます。
stateを利用するには、従来はクラスコンポーネントにする必要があった。
しかし、フックを使うことで、関数コンポーネントの中でフックを使うことができるようになった。
フックはReactをクラスなしに使うための機能である。
そのため、クラス内(クラスコンポーネント内)では機能しない。
クラスはReact開発陣としては推奨していない様子。
そのため、今後始める人はコンポーネントをクラスではなく関数として作成していくことが良い。
再レンダリングの制御
コンポーネントが再レンダリングされる条件は3つ。
- Stateが更新された時
- Propsが変更された時
- 再レンダリングされたコンポーネントの子コンポーネント
このいずれかに当てはまる場合。
React.memo(コンポーネントのメモ化)
React標準の機能。
memo化することで、親コンポーネントの再レンダリングに紐づく不要な再レンダリングを抑制できる。
memo化は積極的に行う。
「再レンダリングされたコンポーネントの子コンポーネント」の子コンポーネントであっても、そのコンポーネントがメモ化されていれば、再レンダリングされることはない。
export const Child1 = () => {
console.log("Child1 レンダリング");
return (
<div style={style}>
<p>Child1</p>
<Child2 />
<Child3 />
</div>
)
}
export const Child1 = memo(() => {
console.log("Child1 レンダリング");
return (
<div style={style}>
<p>Child1</p>
<Child2 />
<Child3 />
</div>
)
});
React.useCallBack(関数のメモ化)
const onClickReset = () => {
setNum(0);
};
const onClickReset = useCallback(() => {
setNum(0);
}, []);
子コンポーネントに関数をpropsで渡している場合は、親コンポーネントの関数を積極的にuseCallBack化して、再レンダリングを抑制する。
グローバルなstate管理
- コンポーネント内のstateをローカルstateと言う。
- コンポーネントを跨いで共有するstateをグローバルstateと言う。
通常、階層構造をきっちり設計した場合、上から下まで3以上の階層になることは普通にある。
その時、上から下までstateをpropsで渡すのはコードが汚れてバケツリレーと呼ばれる状態になる。
そのような無駄なstateの受け渡しを防ぐために、いくつかの方法がある。
ContextでのState管理
React標準の機能。
Redux,Recoil
Reduxは現在主流だが、複雑である。
RecoilはFacebook社製のライブラリであるため、今後主流になりそう。
RecoilはReduxより容易にグローバルStateを扱える。
Redux
Storeというデータストアに対して、
Action,Reducer,Dispatcherという部品を用いて一方向のデータフローを実現する。
Recoil
Atomというデータストアを作る。
Selectorという部品からAtomのデータを取得できる。