欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

React如何使用localStorage及實(shí)現(xiàn)刪除筆記操作過程

 更新時(shí)間:2024年12月18日 10:56:53   作者:練習(xí)兩年半的工程師  
這篇文章主要介紹了React如何使用localStorage及實(shí)現(xiàn)刪除筆記操作過程,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧

1. 初始化notes

以下這段代碼完成了這些操作:

  • 調(diào)用 localStorage.getItem("notes") 從瀏覽器的本地存儲(chǔ)中獲取名為 “notes” 的數(shù)據(jù)。
  • 使用 JSON.parse 將獲取到的字符串解析成數(shù)組。
  • 如果本地存儲(chǔ)中沒有 “notes” 數(shù)據(jù)(返回值為 null),則默認(rèn)將 notes 設(shè)置為空數(shù)組 []。
const [notes, setNotes] = React.useState(
    JSON.parse(localStorage.getItem("notes")) || []
  )

useState鉤子

useState 是 React 的一個(gè)鉤子,用于在函數(shù)組件中引入狀態(tài)。
它返回一個(gè)數(shù)組,有兩個(gè)元素:

  • 當(dāng)前狀態(tài)值(這里是 notes)。
  • 更新狀態(tài)的函數(shù)(這里是 setNotes)。

localStorage

  • localStorage 是瀏覽器提供的 API,用于在本地存儲(chǔ)鍵值對(duì)數(shù)據(jù)。
  • localStorage.getItem("notes")localStorage 中獲取鍵為 “notes” 的數(shù)據(jù),返回的結(jié)果是一個(gè)字符串。

JSON.parse

  • localStorage 中存儲(chǔ)的所有數(shù)據(jù)都是字符串。
  • JSON.parse 將字符串解析為 JavaScript 對(duì)象。

如果存儲(chǔ)的數(shù)據(jù)是一個(gè) JSON 字符串,例如:“[1, 2, 3]”,調(diào)用 JSON.parse 后會(huì)得到 [1, 2, 3]。

|| 運(yùn)算符

  • || 是邏輯或運(yùn)算符,用來提供一個(gè)默認(rèn)值。
  • 如果 localStorage.getItem("notes") 返回 null(即沒有找到 “notes” 鍵),JSON.parse(localStorage.getItem("notes")) 的結(jié)果會(huì)是 null。
  • 在這種情況下,表達(dá)式的右側(cè)([])會(huì)被返回,表示 notes 的初始值是一個(gè)空數(shù)組。

2. 每次notes發(fā)生改變時(shí),將notes保存到localStorage

  React.useEffect(() => {
    localStorage.setItem("notes", JSON.stringify(notes))
  }, [notes])

useEffect 是 React 的一個(gè)鉤子,用于在函數(shù)組件中處理副作用。

  • 副作用通常指與組件渲染邏輯無關(guān)的行為,例如:數(shù)據(jù)獲取、訂閱、手動(dòng) DOM 操作、或者日志記錄等。

它的語法如下:

React.useEffect(effectFunction, dependencies);

effectFunction 是一個(gè)函數(shù),在特定條件下運(yùn)行。
dependencies 是一個(gè)數(shù)組,控制 effectFunction 的運(yùn)行時(shí)機(jī)。

localStorage.setItem 是瀏覽器提供的 API,用于向 localStorage 中存儲(chǔ)鍵值對(duì)。
它接受兩個(gè)參數(shù):

  • 鍵:存儲(chǔ)數(shù)據(jù)的名稱(這里是 “notes”)。
  • 值:存儲(chǔ)的具體數(shù)據(jù),必須是字符串。

JSON.stringify(notes)

  • 將 notes 轉(zhuǎn)換為 JSON 格式的字符串,因?yàn)?localStorage 只能存儲(chǔ)字符串?dāng)?shù)據(jù)。

當(dāng)組件渲染后并且 notes 發(fā)生變化時(shí):

  • useEffect 會(huì)被觸發(fā)。
  • localStorage.setItem(“notes”, JSON.stringify(notes)) 將最新的 notes 數(shù)組保存到本地存儲(chǔ)中。

如果 notes 沒有變化:

  • 即使組件重新渲染,useEffect 不會(huì)運(yùn)行,因?yàn)?notes 的值沒有改變。

3. 什么是 Lazy State Initialization?

通常情況下,useState 的初始值是直接計(jì)算出來的:

const [state, setState] = React.useState(computeInitialState());
  • 這里 computeInitialState() 會(huì)在組件每次渲染時(shí)立即執(zhí)行,即使結(jié)果只需要在初次渲染時(shí)使用。
  • 如果 computeInitialState 是一個(gè)復(fù)雜的計(jì)算函數(shù),就會(huì)浪費(fèi)性能。

為了解決這個(gè)問題,React 提供了一種惰性初始化的方法:通過向 useState 傳遞一個(gè)函數(shù),而不是直接傳遞計(jì)算結(jié)果。這種函數(shù)只會(huì)在組件第一次渲染時(shí)執(zhí)行,之后不會(huì)再次調(diào)用。

惰性初始化

const [state, setState] = React.useState(() => computeInitialState());
  • 當(dāng)傳遞一個(gè)函數(shù)給 useState 時(shí),React 只會(huì)在組件初次渲染時(shí)調(diào)用這個(gè)函數(shù)來計(jì)算初始狀態(tài)。
  • 后續(xù)的狀態(tài)更新不再調(diào)用此函數(shù)。

4. 在React中實(shí)現(xiàn)刪除筆記的操作

<button 
    className="delete-btn"
    onClick={(event) => props.deleteNote(event, note.id)}
>
    <i className="gg-trash trash-icon"></i>
</button>

<button> 元素

  • HTML 的按鈕標(biāo)簽,用于定義一個(gè)可點(diǎn)擊的交互元素。
  • 在 React 中, 可以綁定事件和自定義屬性,并觸發(fā)相關(guān)的事件處理程序。

回調(diào)函數(shù)中的 (event) => props.deleteNote(event, note.id) 是一個(gè)箭頭函數(shù),執(zhí)行時(shí)調(diào)用 props.deleteNote 方法,并將兩個(gè)參數(shù)傳遞給它:

  • event:原生的點(diǎn)擊事件對(duì)象,提供有關(guān)點(diǎn)擊的信息(如目標(biāo)元素、鼠標(biāo)位置等)。
  • note.id:當(dāng)前筆記的唯一標(biāo)識(shí)符,用于指定要?jiǎng)h除的具體筆記。

<i> 是 HTML 的行內(nèi)元素,通常用作圖標(biāo)的占位符。

  function deleteNote(event, noteId){
    event.stopPropagation()
    setNotes(oldNotes => oldNotes.filter(note => note.id !== noteId))
  }

event.stopPropagation()
作用:

  • 阻止事件從當(dāng)前元素傳播到父元素或其他祖先元素(即阻止事件冒泡)。
  • 防止刪除按鈕的點(diǎn)擊事件觸發(fā)父組件的其他事件處理邏輯(如整個(gè)筆記項(xiàng)的點(diǎn)擊事件)。

場景舉例:
假設(shè)筆記項(xiàng)的外層組件有一個(gè)點(diǎn)擊事件綁定:

<div onClick={() => console.log("Note clicked!")}>
    <button onClick={(event) => deleteNote(event, noteId)}>Delete</button>
</div>

如果沒有 event.stopPropagation()

  • 點(diǎn)擊刪除按鈕時(shí),既會(huì)觸發(fā) deleteNote,又會(huì)觸發(fā)外層 divonClick。

有了 event.stopPropagation()

  • 點(diǎn)擊刪除按鈕時(shí),只會(huì)觸發(fā) deleteNote。

箭頭函數(shù) oldNotes => oldNotes.filter(...)
setNotes 接收一個(gè)更新函數(shù),該函數(shù)的參數(shù)是當(dāng)前的狀態(tài)值 oldNotes。
filter 方法:

  • 返回一個(gè)新數(shù)組,其中包含滿足條件的所有元素。
  • 條件:保留 id 不等于 noteId 的筆記,即刪除 noteId 對(duì)應(yīng)的筆記。

完整邏輯
通過 filter 遍歷 oldNotes 數(shù)組:

  • 如果 note.id !== noteId,該筆記被保留。
  • 如果 note.id === noteId,該筆記被過濾掉。

返回的新數(shù)組賦值給 notes,并觸發(fā)組件重新渲染。

5. 刪除按鈕的CSS實(shí)現(xiàn)

.delete-btn {
  display: none;
  background: none;
  border: none;
}

作用

  • 定義刪除按鈕的初始樣式,默認(rèn)情況下按鈕是隱藏的。

屬性解釋

  • display: none;:

隱藏元素,按鈕不占據(jù)布局空間,不可見。

  • background: none;:

移除按鈕的默認(rèn)背景樣式。

  • border: none;:

移除按鈕的默認(rèn)邊框。

.title:hover > .delete-btn {
  display: block;
}

作用

  • 當(dāng)用戶將鼠標(biāo)懸停在 .title 元素上時(shí),其子元素 .delete-btn 顯示出來。

屬性解釋
display: block;

讓 .delete-btn 可見,并以塊級(jí)元素形式顯示。

> .delete-btn

  • 表示只選擇直接子元素 .delete-btn,避免影響其他嵌套更深的 .delete-btn。

實(shí)現(xiàn)邏輯

通過偽類 :hover,動(dòng)態(tài)切換按鈕的顯示狀態(tài),提供更好的用戶交互體驗(yàn)。

.trash-icon {
  cursor: pointer;
}

作用

  • 定義垃圾桶圖標(biāo)的樣式,使其在用戶鼠標(biāo)懸停時(shí)具有點(diǎn)擊效果。

屬性解釋
cursor: pointer;

鼠標(biāo)懸停時(shí)顯示手型指針,表示該元素可點(diǎn)擊。

.gg-trash {
  box-sizing: border-box;
  position: relative;
  display: block;
  transform: scale(var(--ggs,1));
  width: 10px;
  height: 12px;
  border: 2px solid transparent;
  box-shadow:
      0 0 0 2px,
      inset -2px 0 0,
      inset 2px 0 0;
  border-bottom-left-radius: 1px;
  border-bottom-right-radius: 1px;
  margin-top: 4px;
}

作用

  • 定義垃圾桶圖標(biāo)的外觀,包括大小、形狀和整體樣式。

屬性解釋
box-sizing: border-box;

  • 控制元素的寬高計(jì)算方式,包含內(nèi)邊距和邊框。

position: relative;

  • 定義元素為相對(duì)定位,用于配合子元素的絕對(duì)定位。

transform: scale(var(--ggs,1));

  • 使用 CSS 變量 --ggs 控制縮放比例,默認(rèn)為 1。

width: 10px; height: 12px;

  • 定義垃圾桶的寬度和高度。

border: 2px solid transparent;

設(shè)置透明的邊框。

box-shadow
為垃圾桶形狀添加外邊框和內(nèi)部邊框:

  • 0 0 0 2px:外部邊框,2px 寬。
  • inset -2px 0 0 和 inset 2px 0 0:內(nèi)部分隔線。

border-bottom-left-radiusborder-bottom-right-radius

  • 為垃圾桶底部的兩個(gè)角添加圓角。

margin-top: 4px;

在頂部增加間距。

.gg-trash::after {
  background: currentColor;
  border-radius: 3px;
  width: 16px;
  height: 2px;
  top: -4px;
  left: -5px;
}

作用

  • 添加垃圾桶的橫梁部分(通常表示垃圾桶的蓋子)。

屬性解釋
background: currentColor;

使用當(dāng)前文本顏色作為背景顏色。

border-radius: 3px;

添加圓角,使蓋子邊緣更平滑。

width: 16px; height: 2px;

定義橫梁的大小。

top: -4px; left: -5px;

使用絕對(duì)定位將橫梁放置在垃圾桶頂部的位置。

.gg-trash::before {
  width: 10px;
  height: 4px;
  border: 2px solid;
  border-bottom: transparent;
  border-top-left-radius: 2px;
  border-top-right-radius: 2px;
  top: -7px;
  left: -2px;
}

作用

  • 添加垃圾桶的蓋子部分(彎曲的頂部結(jié)構(gòu))。

屬性解釋
width: 10px; height: 4px;:

  • 定義蓋子的寬度和高度。

border: 2px solid;:

設(shè)置蓋子的邊框。

border-bottom: transparent;:

移除蓋子底部的邊框,使其開口朝下。

border-top-left-radius 和 border-top-right-radius:

設(shè)置蓋子頂部的兩個(gè)角為圓角。

top: -7px; left: -2px;:

使用絕對(duì)定位將蓋子放置在垃圾桶頂部。

總結(jié):垃圾桶圖標(biāo)的整體實(shí)現(xiàn)

  • .gg-trash 是垃圾桶的主體,包括邊框、陰影等基礎(chǔ)結(jié)構(gòu)。
  • ::after 添加橫梁(垃圾桶蓋的下部分)。
  • ::before 添加蓋子頂部的彎曲結(jié)構(gòu)。

結(jié)合這些樣式,實(shí)現(xiàn)了一個(gè)完整的垃圾桶圖標(biāo)。

交互效果總結(jié)

  • .delete-btn 默認(rèn)隱藏,用戶鼠標(biāo)懸停在 .title 上時(shí)顯示。
  • 鼠標(biāo)懸停時(shí),垃圾桶圖標(biāo)變?yōu)榭牲c(diǎn)擊狀態(tài),通過樣式 cursor: pointer 提供視覺提示。

6. 查找當(dāng)前筆記id

const [currentNoteId, setCurrentNoteId] = React.useState(
    (notes[0]?.id) || ""
  )
const currentNote = notes.find(note => note.id === currentNoteId) || notes[0]

React.useState

定義一個(gè)狀態(tài)變量 currentNoteId 和其對(duì)應(yīng)的更新函數(shù) setCurrentNoteId。

notes[0]?.id

  • 通過可選鏈操作符 (?.),嘗試訪問數(shù)組 notes 中第一項(xiàng)的 id。
  • 如果 notes 數(shù)組為空或者 notes[0]undefined,notes[0]?.id 返回 undefined 而不會(huì)報(bào)錯(cuò)。

|| ""
如果 notes[0]?.idundefined,currentNoteId 的初始值設(shè)置為空字符串 ""。

效果

如果 notes 數(shù)組非空,currentNoteId 的初始值是第一項(xiàng)筆記的 id。如果 notes 數(shù)組為空,currentNoteId 的初始值是 “”。

notes.find(note => note.id === currentNoteId)

  • 使用 Array.prototype.find() 方法在 notes 數(shù)組中查找 id 等于 currentNoteId 的筆記。
  • find 方法返回第一個(gè)滿足條件的元素。如果沒有找到匹配的元素,返回 undefined。

|| notes[0]
如果沒有找到匹配的筆記(即 find 返回 undefined),使用 || 提供默認(rèn)值,返回 notes[0](數(shù)組的第一項(xiàng))。

到此這篇關(guān)于React自學(xué):如何使用localStorage,以及如何實(shí)現(xiàn)刪除筆記操作的文章就介紹到這了,更多相關(guān)React localStorage刪除筆記內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • React實(shí)現(xiàn)點(diǎn)擊刪除列表中對(duì)應(yīng)項(xiàng)

    React實(shí)現(xiàn)點(diǎn)擊刪除列表中對(duì)應(yīng)項(xiàng)

    本文主要介紹了React 點(diǎn)擊刪除列表中對(duì)應(yīng)項(xiàng)的方法。具有一定的參考價(jià)值,下面跟著小編一起來看下吧
    2017-01-01
  • 詳解如何在React中監(jiān)聽鼠標(biāo)事件

    詳解如何在React中監(jiān)聽鼠標(biāo)事件

    React可以通過使用React事件系統(tǒng)來監(jiān)聽鼠標(biāo)事件,您可以在React組件中通過使用特定的事件處理函數(shù)來注冊和處理鼠標(biāo)事件,本文小編講給大家詳細(xì)介紹一下如何在React中監(jiān)聽鼠標(biāo)事件,需要的朋友可以參考下
    2023-09-09
  • Vite搭建React項(xiàng)目的方法步驟

    Vite搭建React項(xiàng)目的方法步驟

    這篇文章主要介紹了Vite搭建React項(xiàng)目的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • React合成事件詳解

    React合成事件詳解

    這篇文章主要介紹了React合成事件的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用React,感興趣的朋友可以了解下
    2021-05-05
  • react組件中過渡動(dòng)畫的問題解決

    react組件中過渡動(dòng)畫的問題解決

    這篇文章主要為大家介紹了react組件中過渡動(dòng)畫的問題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • react-router-dom?降低版本的兩種方法詳解

    react-router-dom?降低版本的兩種方法詳解

    這篇文章主要介紹了react-router-dom?降低版本的兩種方法,本篇文章就記錄下如何降低 react-router-dom 為 v5 版本的兩種方法,需要的朋友可以參考下
    2022-12-12
  • 在react中使用highlight.js將頁面上的代碼高亮的方法

    在react中使用highlight.js將頁面上的代碼高亮的方法

    本文通過 highlight.js 庫實(shí)現(xiàn)對(duì)文章正文 HTML 中的代碼元素自動(dòng)添加語法高亮,具有一定的參考價(jià)值,感興趣的可以了解一下
    2022-01-01
  • React 組件轉(zhuǎn) Vue 組件的命令寫法

    React 組件轉(zhuǎn) Vue 組件的命令寫法

    本文先介紹兩個(gè)框架的組件共性和不兼容的地方,再介紹react-to-vue的使用和原理,需要的朋友可以參考下
    2018-02-02
  • React 中常用的幾種路由跳轉(zhuǎn)方式小結(jié)

    React 中常用的幾種路由跳轉(zhuǎn)方式小結(jié)

    基本路由跳轉(zhuǎn)是最常見的一種方式,下面介紹React 中常用的幾種路由跳轉(zhuǎn)方式,感興趣的朋友一起看看吧
    2023-12-12
  • 基于react框架使用的一些細(xì)節(jié)要點(diǎn)的思考

    基于react框架使用的一些細(xì)節(jié)要點(diǎn)的思考

    下面小編就為大家?guī)硪黄趓eact框架使用的一些細(xì)節(jié)要點(diǎn)的思考。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-05-05

最新評(píng)論