# React Hook - Custom Hooks ###### tags: `Javascript, React` 這篇會使用 DMEO 來展示如何操作 custom hook 創造一個 hook 來把資料存入 loacalStorage 裡面,讓頁面刷新的時候畫面上的資料可以被保存 ![](https://i.imgur.com/w01vGps.png) # 範例一 操作 locaStorage custom hook ## App.js 使用 custmo hook 的方式只要引入即可使用,但是需要注意命名時必須加入 use 當作前墜詞 比方範例使用就是 use + LocalStorage useLocalStorage 會返回兩個東西: * value 目前的 state * setValue 可以修改 initialValue 的函式用來接收使用者 input 就變成在 useLocalStorage.js 內處理 state 的更新 要注意的是因為要處理的是 loacaStorage 所以初始值的地方要填入 'key' 才能正確取得裡面的 value ```javascript= import './App.css'; import React from 'react'; import useLocalStorage from './useLocalStorage'; export default function App() { const [value, setValue] =useLocalStorage('key','') return ( <input type="text" value={value} onChange={e => setValue(e.target.value)} /> ); } ``` ## useLocalStorage.js 在 custom hook 內會寫入以及取出 value 從 localStorage 來更新 state 1. 首先在 useLocalStorage 內傳入兩個參數 * 第一個是 key: 'key' 這邊就是要從 localStorage 內取出資料的名稱 * 第二個參數 initailValue 則是 App.js 內的 setValue 設定的 value 值也就是使用者輸入的值 2. 接下來觸發的 useState 內部的函式 getSavedValue 帶入 key, initialValue 參數會返回 * 如果有修改則返回從 localStorage 取出的值 * 如果沒有修改則返回 initialValue 3. 再來操作 useEffect 把當下的 value state 傳進去 localStorage ,並且只監聽當 value 更新時才會觸發(使用者沒有輸入東西則不觸發) 4. 最後返回 vaule, setValue 回去 App.js ```javascript= import React,{useState, useEffect} from 'react' function getSavedValue(key, initialValue){ const savedValue = JSON.parse(localStorage.getItem(key)) if(savedValue) return savedValue return initialValue } export default function useLocalStorage(key,initialValue) { // 這邊的 vaule 就是 initialValue 或是 savedValue const [value, setValue] = useState(()=>{ return getSavedValue(key,initialValue) }) // 這邊 useEffect 監聽 value ,所以 value 有更新才會觸發並且把新的 value (也就是 savedValue 存進去 localStorage) useEffect(()=>{ localStorage.setItem(key,JSON.stringify(value)) },[value]) // 最後返回當前的 state value 以及可以修改 initialValue 變成 savedValue 的函式 setValue return [value, setValue] } ``` # 範例二 這邊我要操作每當 value 更新的時候要 log 它的內容 ![](https://i.imgur.com/qOgW8cI.png) ## useUpdateLogger.js 這邊操作也很容易就直接針對 useUpdateLogger 內部操作 useEffect 後內部寫入 console.log 並且填入 value ,並且監聽 value 這樣就會只有當 vaule 更新的時候才會 log 出 vaule 的內容了 ```javascript= import React,{useEffect} from 'react' export default function useUpdateLogger(value) { useEffect(() => { console.log(value); },[value]) } ``` ## App.js 使用方式也很簡單只要引入並且直接呼叫並且帶入想要操作的參數即可 ```javascript= import './App.css'; import React from 'react'; import useLocalStorage from './useLocalStorage'; import useUpdateLogger from './useUpdateLogger'; export default function App() { const [value, setValue] =useLocalStorage('key','') useUpdateLogger(value) const margin ={ margin:'5rem' } return ( <input type="text" value={value} onChange={e => setValue(e.target.value)} style={margin}/> ) } ``` 這個範例主要想說明的是 可以針對各種 state 拉出來做操作,不管是想要減少重複撰寫或是為了可讀性,這樣的操作非常容易就可以達成 ```javascript= import React,{useEffect} from 'react' export default function useUpdateLogger(填入想操作的 state ) { useEffect(() => { // 填入想要操作的邏輯 },[ 填入想操作的 state]) } ```