//tips
//smart contract
フックの使い方を見てきたが、欠点としてはステートの値をずっと保持することはできず、現在のページにおいてのみ値を保持する。そのため別の機会にアクセスした時には情報が消えてしまうことになる。
値を保持する一番簡単な方法はローカルストレージを使用することで、これはjsに搭載されている機能。ローカル環境に値を保管しておくもので、windowオブジェクトのlocalStorageプロパティを扱い、ローカルストレージにアクセスする。
保管先としては、webブラウザの中になる。
import React, { useState } from 'react'
function usePersist(ky, initVal) {
const key = "hooks:" + ky
const value = () => {
try {
const item = window.localStorage.getItem(key)//ローカルからの値の取り出し
return item ?
//値が存在したらjson形式のテキストからオブジェクトを生成し返す
JSON.parse(item) : initVal
} catch (err) {
console.log(err)
return initVal;
}
}
const setValue = (val) => {
try {
setSavedValue(val)
//valの値をjsonテキストに変換しローカルストレージに保管
window.localStorage.setItem(key, JSON.stringify(val))
} catch (err) {
console.log(err)
}
}
const [savedValue, setSavedValue] = useState(value)
//savedValueは値を保存するステート、setValueは値をローカルストレージに保管する
return [savedValue, setValue]
}
export default usePersist
これがベースのコンセプトになるよう。簡単なform入力をテスト。
import React, { useState, useEffect } from 'react'
import './App.css'
import usePersist from './Persist'
function AlertMessage(props) {
const [name, setName] = useState("")
const [mail, setMail] = useState("")
const [age, setAge] = useState(0)
const [mydata, setMydata] = usePersist("mydata", null)
const onChangeName = (e)=> {
setName(e.target.value)
}
const onChangeMail = (e)=> {
setMail(e.target.value)
}
const onChangeAge = (e)=> {
setAge(e.target.value)
}
const onAction = (e)=> {
const data = {
name: name,
mail: mail,
age: age
}
setMydata(data)
}
return <div className="alert alert-primary h5 text-primary">
<h5 className="mb-4">{JSON.stringify(mydata)}</h5>
<div className="form-group">
<label className="h6">Name</label>
<input type="text" onChange={onChangeName}
className="form-control" />
</div>
<div className="form-group">
<label className="h6">Mail</label>
<input type="mail" onChange={onChangeMail}
className="form-control" />
</div>
<div className="form-group">
<label className="h6">Age</label>
<input type="number" onChange={onChangeAge}
className="form-control" />
</div>
<button onClick={onAction}
className="btn btn-primary">
Save it!
</button>
</div>
}
// ベース・コンポーネント
function App() {
return (
<div>
<h1 className="bg-primary text-white display-4 ">React</h1>
<div className="container">
<h4 className="my-3">Hooks sample</h4>
<AlertMessage />
</div>
</div>
)
}
export default App
Webブラウザの開発ツールからアプリケーションを選択し、localstorageのlocalhost:3000を確認すると、
{name: "naki", mail: "naki@naki.com", age: "20"}
age: "20"
mail: "naki@naki.com"
name: "naki"
のような形式で表示され、保存されていることがわかる。
const [mydata, setMydata] = usePersist("mydata", null)でmydataに保管した値が代入され、setMydataで値の設定、データ保管はonClickに割り当てたonActionに実行している。
簡単なメモアプリを作成していく。
アプリとして作成する場合にはapp.jsだけではなく、コンポーネントを別のファイルとして作成していきたい。
Index.js:ベーススクリプト
App.js:アプリのベースコンポーネント
Persist.js:usePersistフックスクリプト
Memopage.js:目元フォームをまとめてページ表示するコンポーネント
Memo.js,Item.js:メモ表示とメモの各項目の表示を担当するコンポーネント
Addform.js,findform.js,delform.js:メモの作成・検索・削除フォーム用のコンポーネント
メモに記載するデータは、テキストmessageと作成時間createdとする。この二つを持つオブジェクトとしてメモを用意し、配列を保管して管理する。
import './App.css'
import MemoPage from './memo/MemoPage'
function App() {
return (
<div>
<h1 className="bg-primary text-white display-4 ">React</h1>
<div className="container">
<h4 className="my-3">Memo.</h4>
<MemoPage />
</div>
</div>
)
}
export default App
App.jsにはMemoPageコンポーネントに飛ばすシンプルな内容を記載。index.jsは変更なし。
MemoPage.jsはステートフックを永続化するPersistを読み込み
import usePersist from '../Persist'
import Memo from './Memo';
import AddForm from './AddForm';
import FindForm from './FindForm';
import DelForm from './DelForm';
function MemoPage() {
const [mode, setMode] = usePersist('mode', 'default')
return (
<div>
<h5 className="my-3">mode: {mode}</h5>
<div className="alert alert-primary pb-0">
<AddForm />
<FindForm />
<DelForm />
</div>
<Memo />
</div>
)
}
export default MemoPage
独自フックの右辺と左辺の関係がいまいち把握できていなかったので振り返った。
独自フックの引数は、独自フックの関数機能使用時に渡す値を引数としてとるもので、まずは独自関数の定義パートとそれの使用パートに分かれている。
その使用パートで const [mode, setMode] = usePersist('mode', 'default’)のように引数を受け取り、定義されている関数を実行することになる。
function usePersist(ky, initVal) {
const key = "hooks:" + ky
const value = () => {
try {
const item = window.localStorage.getItem(key)
return item ? JSON.parse(item) : initVal
} catch (err) {
console.log(err)
return initVal;
}
}
const setValue = (val) => {
try {
setSavedValue(val)
window.localStorage.setItem(key, JSON.stringify(val))
} catch (err) {
console.log(err)
}
}
const [savedValue, setSavedValue] = useState(value)
return [savedValue, setValue]
}
気にしておく必要があるのは const [mode, setMode] = usePersist('mode', 'default’)がMemoコンポーネントでも使用されること。
スクリプトを頑張って読み込んでいると、reactを拡張できるnext.jsを使えばもっと簡単にできるよとのこと。早速導入してみる。
npx create-next-app next_app