概要
React.js&Next.js超入門 第2版を拝読し、React.js・Next.jsの学習を行ったためその内容をアウトプットする。
基本的な使い方
エレメントの生成
// ここで生成しているのはDOMではなく仮想DOM
let element = React.createElement(
タグ名, 属性, 中に組み込まれる記述
)
属性の箇所は何もなければ{}
を記載する。
レンダリング
ReactDOM.render(仮想DOMのエレメント, 本来のDOM)
JSX
1つのエレメントを生成する。
Javascriptのコードを古いJSにコンパイラする。
以下記述で使用可能である。
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
// ここに記載
</script>
JSXでは、JavaScriptの記述を{}
で使用する。
// 変数
{変数}
// 条件分岐
{真偽値 && JSXの記述}
// 三項演算子
{条件 ? trueの場合 : falseの場合;
※条件分岐だと、真偽値が満たされる場合に右側のJSXの記述が表示される。
配列
使用例
let data = [
<li className="list-group-item">One</li>,
<li className="list-group-item">Two</li>,
<li className="list-group-item">Three</li>
]
<ul className="list-group mt-4">
{data}
</ul>
<ul>タグ
にliタグ
が連なる。
map
使用例
配列を格納したdata
という変数にmapを使用している。
let data = [
{name:'Yamada', mail:'yamada@test', age:45},
{name:'Hanako', mail:'hanako@test', age:37},
]
{data.map((value) =>(
<tr>
<td>{value.name}</td>
<td>{value.mail}</td>
<td>{value.age}</td>
</tr>
))}
即時実行関数も使用可能である。
{(()=> JSX )}
コンポーネント
概要
表示内容・データ・処理を1つのオブジェクトにまとめたもので、画面に表示される部品である。
コンポーネント名の1文字目は必ず大文字で記載する必要がある。
関数コンポーネント
定義
function コンポーネント名(){
return /* JSXの記述 */
}
呼び出し
<コンポーネント名/>
関数コンポーネントの引数
関数コンポーネントの引数ではタグの属性を使用できる
// 関数定義
function Com(att){
// 使用例
return <p className={att.fontSize}>Hello {att.name}</p>
}
// 呼び出し側
<Com name="Taro" fontSize="h2" />
クラスコンポーネント
クラス基本的な記載は以下
class クラス名 {
constructor(props){
super(props)
// 初期化処理
}
// プロパティやメソッドを記載する
メソッド名 (){
// 処理
}
}
constructorメソッド
オブジェクトの初期化を行う。
引数は1つだけ用意されており、属性の値をオブジェクトにまとめたものが渡される。
super()
の記述では、後述するextendsで継承しているクラスのconstructorを呼び出すための記述である。
コンポーネントのクラス
コンポーネントのクラスでは、extendsを使用して定義する。
class クラス名 extends 継承するクラス {}
自分でコンポーネントを定義する場合はReact.Componnt
というコンポーネントの機能を取り揃えたクラスを継承して作成する。
renderメソッド
コンポーネントクラスには必ずrenderメソッドが必要である。
render(){
returun // JSXの記述
}
Creat React App
読み込まれる順番は以下である。
- index.htmlが読み込まれる。
- index.htmlを読み込む際にindex.jsが読み込まれて実行される
- index.jsの中でAppコンポーネントが読み込まれ表示される。
以下で各ファイルの説明を行う。
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
noscript
はJavaScriptが動作しない環境の時に表示される。
Reactでは、Reactを組み込む用のタグが1個あるというのが一般的な実装方法である。
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
import reportWebVitals from './reportWebVitals';
上記でアプリのパフォーマンスなどを分析する。
<React.StrictMode></React.StrictMode>
上記で厳格モードを設定可能である。
<App />
上記でApp
コンポーネントを読み込んでいる。
ステート
概要
- Componentを継承したクラスコンポーネントで利用する値の保管庫。
- コンポーネントの状態を扱い、操作することができる。
- ステートを変更すれば自動的に表示が更新される。
ステートはクラスコンポーネントのみで使用できていたが、フックを使用することで関数コンポーネントで使用できるようになった。
プロパティ
クラスの値を保管しておくのに使用する。
コンポーネントに限らずクラス全般で利用される。
属性
コンポーネントとの属性をまとめて保管するためのもので基本的にreadのみ。
ステートの初期化
class App extends Component {
constructor(props){
super(props);
this.state = {
msg:'Hello Component.',
}
}
this.state.msg
}
ステートの更新
this.setState( { 値 } )
子エレメントの受け渡しを下記で実施できる。
class App extends Component {
input = ''
constructor(props){
super(props)
}
render(){
return
<Message title="Children!">
コンテンツ
</Message>
}
}
class Message extends Component {
render(){
//受け取り
this.props.children
}
}
入力した値をチェックする。
<input type="text" className="form-control"
required pattern="[A-Za-z _,.]+" />
required
・・・必須
pattern
・・・正規表現
コンテキスト
概要
コンポーネント全体で共通して使用可能である。
使用方法
以下をクラスの外で定義する。
const 変数 = React.createContext(値)
以下で使用可能である。
// 「static contextType」という記述は固定で記載する。クラス内にこの記述をするとコンテキストがそのクラスで使用可能になる。
static contextType = コンテキスト
// 以下にまとめられる。
this.context
// 更新する。
this.context.message = "test"
一部のコンポーネントでコンテキストの値を変更する
const a = React.createContext(変更前の値)
<コンポ―ネント/>
<a.Provider value={変更後の値}>
<コンポ―ネント/>
</a.Provider>
Provider
内にあるコンポーネントのみコンテキストの値が変更されている。
Hooks
Reactでは、ステートを関数コンポーネントで使用することができなかったが、Hooksが出てきたことによって使用可能になった。
クラスコンポーネントでは、thisやbindなどの記述が複雑になりがちだったため、Hooksを使用した関数コンポーネントを使用することがおすすめ。
ステートを含むコンポーネントの処理を再利用することができる。
Hooksの種類
Hooksにはいくつかの種類がある。
ステートフック
useState
を使用してステートフックを作成できる。
import React, { useState } from 'react'
const [変数A, 変数B] = useState(初期値)
変数A・・・ステートの値、現在のステートの値が得られる。
変数B・・・ステートの値を変更する関数。この変数に引数をつけて呼び出すことでステートの値を変更する。
※useStateを使用する場合(ステートの種類によって異なる)
簡易的な仕様イメージは以下である。
const [count, setCount] = useState(0)
const clickFunc = () => {
setCount(count + 1)
}
<button onClick={clickFunc}>{count}</button>
buttonタグをクリックするとclickFunc
関数が実行され、ステートの値を変更するsetCount
関数が呼び出される。
setCount
関数では、count
ステートに1を足すようにしている。
よってbutton
タグをクリックするとcountの数が1ずつ増えていく。
関数コンポーネントの変数とステート
クラスコンポーネントは状態維持できるが、関数は呼び出される度に変数が初期化される。
常に持っておきたい値はステートとして使用するべきである。
複数の関数コンポーネント
以下の用に使用する
// 関数コンポーネントの定義
function a() {
return // 値
}
function b() {
return // 値
}
function c() {
// 関数コンポーネントの呼び出し
<a />
<b />
return // 値
}
値の受け渡し
const [msg, setMsg] = useState("This is sample messsage!")
<AlertMessage message={msg} setMsg={setMsg}/>
function AlertMessage(props) {
// propsで受け取ることができる
props.message
props.setMsg()
}
ステートを変更すると画面が更新される。(変数を変更しても画面は変わらない)
副作用フック
- 値の変更などがあった場合に呼び出される。
- 複数定義可能である。
基本形
useEffect( 関数 )
関数が実行される条件を記載できる。
useEffect( 関数 ), [ ステート ] )
引数のステートが変更された場合のみ関数が実行される。
独自フック
ステートフックのように戻り値が「値を得る変数と変更する関数」で固定されておらず、戻り値は複数でも値でも関数でも良い。
基本形
function use○○ (){
const ステート
const 関数
return [ 値 ]
}
必ず関数名はuse
から始める。
戻り値は配列を使用する。
ローカルストレージ
ステートはリロードしたら消えてしまう。
windowオブジェクトのlocalStorage
というプロパティを使用することでローカルストレージを使用することが可能である。
キーは値の名前のようなものであり、指定のキーから値を取得することができる。
変数 = wondow.localStorage.getItem(キー)
値を指定のキーで保管する。
wondow.localStorage.setItem(キー,値)
※window
は省略可能。
Next.js
Nextの利点
- ルーティンングを使用できる。
- データとのやりとりを行うAPIを簡単に作成できる。
-
React.js
と異なり、複数ページを持つことができる。
他にもあるが、本書で取り上げられていたのは上記3つ。
npx create-next-app [プロジェクト名]
// TypeScriptを使用する場合
npx create-next-app@latest --ts
上記コマンドでプロジェクトを作成できる。
nodeのバージョンが14だとエラーになったので臨機応変にバージョンの変更を行う必要がある。
Next.jsでは内部ではJSXを使用して具体的な「HTMLを使用しているが、HTMLファイルを直接使用することなく、JSファイルで対応する。
style
基本的にstyles
フォルダ内のCSSに記載してそれをimport
する形が好ましいが、JSXで以下の記述をすることでもCSSを設定可能である。
<style jsx>{`
h1 {
text-align: center;
}
`}</style>
header
headerを毎回index.js
に記載するのは手間である場合は、別ファイルにHeader
の情報を記載してexport
し、必要な場合はimport
して使用することが望ましい。
export default function Header(props) {
return (
<Head>
</Head>
)
}
Linkコンポーネント
aタグと同じようにリンクを作成することができる。
コンポーネントの内部はaタグ
でなくとも構わないのでpタグ
やbutton
なども使用することができる。
import Link from 'next/link'
<Link href="/">
<a></a>
</Link>
子エレメントの受け渡し
export default function コンポーネント名(props) {
// childrenで使用可能。
props.children
}
<コンポーネント名>
子エレメント
</ コンポーネント名>
画像
画像を扱う場合にもコンポーネント化することで使い回しすることができ、Next.jsらしい使用方法である。
画像を扱う場合に、src属性を使用する際は、publicフォルダのファイル類はサーバー直下にあるように扱われるので、直下にあるファイルは./
から記載すると良い
<img src=./ファイル名>
API
APIにアクセスする方法はいくつかあるが、代表的なものにfetch APIがある。
fetch( [アクセスするURL] ).then( res => その後の処理 )
使用例
ステートを定義しておき、fetchを使用してAPIを呼び出した後のthenメソッド内の処理でステートの関数を使用してAPIの返却値を関数の引数にあててステートの変数を変更している。
const [data, setData] = useState({message:'', data:[]})
fetch(url)
.then(res=> res.json())
.then(res=> setData(res))
SWR
インストール
npm install swr
使用例
// JSONデータを取得したい場合
const fetcher = (...args) => fetch(...args).then(res => res.json())
// textデータを取得したい場合
const func = (...args)=> fetch(...args).then(res => res.text())
export default function Home() {
const { data, error } = useSWR('/data.json', fetcher)
next.jsでは、デフォルトで以下のURLにアクセスするとpages/api/hello.jsというファイルにアクセスし、JSONデータを返却してくれる。
http://localhost:3000/api/hello
特殊な変換
id = req.query.id
↓
{query: {id} = req
apiフォルダ下に`[id].jsというファイルを作成すると
パスのid部分を取得することができる。
/〇〇/〇〇
のようなパスの場合は
[...params].jsというファイルを作成し
const {
query: {params: [id, item]}
} = req
上記のような配列の形で受け取る。
idやparamsはquery内の名称であり自作することができる。
以上。