Master Course

本ページはお試し版です。コース全編をご希望の方はこちらからどうぞ。

SECTION 6: Reactをもっと使ってみよう

  • 1このセクションで学ぶこと
  • 2Contextの導入1(Contextの機能確認)
  • 3Contextの導入2(propsの整理)
  • 4try/catch
  • 5ダークモード開発1(ダークモードの仕組み)
  • 6ダークモード開発2(ダークモードの実装)
  • 7ダークモード開発3(カスタムHook)
  • 8履歴表示機能の開発1(機能の確認)
  • 9履歴表示機能の開発2(配列へのデータ保存方法)
  • 10履歴表示機能の開発3(useEffectの使い方)
  • 11履歴表示機能の開発4(履歴削除機能の実装)
  • 12履歴表示機能の開発5(条件付きレンダリング)
  • 13コメント投稿機能の開発1(投稿機能の実装)
  • 14コメント投稿機能の開発2(楽観的更新の導入)
  • 15メタデータの追加
  • 16デプロイの紹介(参考情報)

Section 6: Reactをもっと使ってみよう

  • 1このセクションで学ぶこと
  • 2Contextの導入1(Contextの機能確認)
  • 3Contextの導入2(propsの整理)
  • 4try/catch
  • 5ダークモード開発1(ダークモードの仕組み)
  • 6ダークモード開発2(ダークモードの実装)
  • 7ダークモード開発3(カスタムHook)
  • 8履歴表示機能の開発1(機能の確認)
  • 9履歴表示機能の開発2(配列へのデータ保存方法)
  • 10履歴表示機能の開発3(useEffectの使い方)
  • 11履歴表示機能の開発4(履歴削除機能の実装)
  • 12履歴表示機能の開発5(条件付きレンダリング)
  • 13コメント投稿機能の開発1(投稿機能の実装)
  • 14コメント投稿機能の開発2(楽観的更新の導入)
  • 15メタデータの追加
  • 16デプロイの紹介(参考情報)

履歴表示機能の開発4(履歴削除機能の実装)

動画のテキスト【履歴表示機能の開発4(履歴削除機能の実装)

履歴の削除とはどのような操作なのか考えてみると、これは単に「localStorageの『history』を消すこと」だとわかります。なので次のfunctionを追加しましょう。

// History.jsx ... useEffect(() => { const savedUrl = JSON.parse(localStorage.getItem("history")) savedUrl && setImgUrl(savedUrl) }, [contextValues.mealData]) // ⬇追加 const handleDeleteHistory = () => { localStorage.removeItem("history") } // ⬆追加 return ( ...

removeItem()により、カッコ内で指定した名前のデータがlocalStorageから削除されます。もしすべてのデータを削除したい場合にはclear()を使いますが、今回それを使うとダークモードの「color-mode」も消されてしまうので、removeItem()を使います。次はボタンを追加してください。

// History.jsx return ( <ul> // ⬇追加 <button onClick={handleDeleteHistory}>削除</button> {imgUrl.map(url => <li key={url}> ...

保存して「Application」タグを開きましょう。「削除」ボタンを押すと「history」が消え、履歴が削除されたのがわかります。しかし履歴画像はブラウザに表示されたままで、リロードしてようやく変更が反映されます。そのため、「削除」ボタンが押されたときにレンダリングを起こすようにしましょう。レンダリングはstateを変更することで起こせるので、stateを更新する次のコードを追加します。

// History.jsx ... const handleDeleteHistory = () => { localStorage.removeItem("history") setImgUrl([]) // 追加 } return ( ...

これで「削除」ボタンを押して履歴を削除したときにレンダリングも起き、画像が消えるようになります。

検索履歴の表示と削除の仕組みが完成したので、コードを整理しましょう。History.jsxのコードをcontext/index.jsxに移動します。

// context/index.jsx // ⬇追加 import { createContext, useActionState, useState, useEffect } from "react" import { useNavigate } from "react-router-dom" import { useDarkMode } from "../hooks/useDarkMode" import { addHistory } from "../utils/addHistory" export const AppContext = createContext() const ContextProvider = (props) => { const [imgUrl, setImgUrl] = useState([]) // 追加 const [returnedMealData, getMealDataAction, isPending] = useActionState(getMealData, "") const [theme, handleThemeSwitch] = useDarkMode() ... // ⬇追加 useEffect(() => { const savedUrl = JSON.parse(localStorage.getItem("history")) savedUrl && setImgUrl(savedUrl) }, [contextValues.mealData]) const handleDeleteHistory = () => { localStorage.removeItem("history") setImgUrl([]) } // ⬆追加 const contextValues = { loading: isPending, ...

[]内のstateと、contextValuesのコードを変更します。

// context/index.jsx ... useEffect(() => { const savedUrl = JSON.parse(localStorage.getItem("history")) savedUrl && setImgUrl(savedUrl) }, [returnedMealData]) // 変更 const handleDeleteHistory = () => { localStorage.removeItem("history") setImgUrl([]) } const contextValues = { imgUrl: imgUrl, // 追加 loading: isPending, theme: theme, handleThemeSwitch: handleThemeSwitch, mealData: returnedMealData, getMealDataAction: getMealDataAction, handleDeleteHistory: handleDeleteHistory, // 追加 } return ( ...

History.jsxのコードは次のようになります。<button>タグに改行を入れてあります。

// History.jsx import { use } from "react" import { AppContext } from "../context" const History = () => { const contextValues = use(AppContext) return ( <ul> <button onClick={contextValues.handleDeleteHistory}> 削除 </button> {contextValues.imgUrl.map(url => <li key={url}> <img src={url} alt="meal-image"/> </li> )} </ul> ) } export default History