您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關(guān)React中使用事件驅(qū)動(dòng)進(jìn)行狀態(tài)管理的方法的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。
自 Hook 被引入 React 以來(lái),Context API 與 Hook 庫(kù)在應(yīng)用狀態(tài)管理中被一起使用。但是把 Context API 和 Hooks(許多基于 Hooks 的狀態(tài)管理庫(kù)建立在其基礎(chǔ)上)組合的用法對(duì)于大規(guī)模應(yīng)用來(lái)說(shuō)可能效率不高。
由于必須創(chuàng)建一個(gè)自定義的 Hook 才能啟用對(duì)狀態(tài)及其方法的訪問(wèn),然后才能在組件中使用它,所以在實(shí)際開(kāi)發(fā)中很繁瑣。這違反了 Hook 的真正目的:簡(jiǎn)單。但是對(duì)于較小的應(yīng)用,Redux 可能會(huì)顯得太重了。
今天我們將討論 Context API 的替代方法:Storeon。 Storeon 是一個(gè)微型的、事件驅(qū)動(dòng)的 React 狀態(tài)管理庫(kù),其原理類似于 Redux。用 Redux DevTools 可以查看并可視化狀態(tài)操作。 Storeon 內(nèi)部使用 Context API 來(lái)管理狀態(tài),并采用事件驅(qū)動(dòng)的方法進(jìn)行狀態(tài)操作。
store 是在應(yīng)用程序狀態(tài)下存儲(chǔ)的數(shù)據(jù)的集合。它是通過(guò)從 Storeon 庫(kù)導(dǎo)入的 createStoreon()
函數(shù)創(chuàng)建的。
createStoreon()
函數(shù)接受模塊列表,其中每個(gè)模塊都是一個(gè)接受 store
參數(shù)并綁定其事件監(jiān)聽(tīng)器的函數(shù)。這是一個(gè)store 的例子:
import { createStoreon } from 'storeon/react' // todos module const todos = store => { store.on(event, callback) } export default const store = createStoreon([todos])
Storeon 中的 store 是模塊化的,也就是說(shuō),它們是獨(dú)立定義的,并且沒(méi)有被綁定到 Hook 或組件。每個(gè)狀態(tài)及其操作方法均在被稱為模塊的函數(shù)中定義。這些模塊被傳遞到 createStoreon()
函數(shù)中,然后將其注冊(cè)為全局 store。
store 有三種方法:
store.get()
– 用于檢索狀態(tài)中的當(dāng)前數(shù)據(jù)。
store.on(event, callback)
– 用于把事件偵聽(tīng)器注冊(cè)到指定的事件名稱。
store.dispatch(event, data)
– 用于發(fā)出事件,并根據(jù)定義的事件要求將可選數(shù)據(jù)傳遞進(jìn)來(lái)。
Storeon 是基于事件的狀態(tài)管理庫(kù),狀態(tài)更改由狀態(tài)模塊中定義的事件發(fā)出。 Storeon 中有三個(gè)內(nèi)置事件,它們以 @
開(kāi)頭。其他事件不帶 @
前綴定義。三個(gè)內(nèi)置事件是:
@init
– 在應(yīng)用加載時(shí)觸發(fā)此事件。它用于設(shè)置應(yīng)用的初始狀態(tài),并執(zhí)行傳遞給它的回調(diào)中的所有內(nèi)容。
@dispatch
– 此事件在每個(gè)新動(dòng)作上觸發(fā)。這對(duì)于調(diào)試很有用。
@changed
– 當(dāng)應(yīng)用狀態(tài)發(fā)生更改時(shí),將觸發(fā)此事件。
注意:store.on(event,callback)
用于在我們的模塊中添加事件監(jiān)聽(tīng)器。
為了演示在 Storeon 中如何執(zhí)行應(yīng)用程序狀態(tài)操作,我們將構(gòu)建一個(gè)簡(jiǎn)單的 notes 程序。還會(huì)用 Storeon 的另一個(gè)軟件包把狀態(tài)數(shù)據(jù)保存在 localStorage
中。
假設(shè)你具有 JavaScript 和 React 的基本知識(shí)。你可以在 https://github.com/Youngestde... 上找到本文中使用的代碼。
在深入探討之前,讓我們先勾勒出 Notes 程序所需的項(xiàng)目結(jié)構(gòu)和依賴項(xiàng)的安裝。從創(chuàng)建項(xiàng)目文件夾開(kāi)始。
mkdir storeon-app && cd storeon-app mkdir {src,public,src/Components} touch public/{index.html, style.css} && touch src/{index,store,Components/Notes}.js
接下來(lái),初始化目錄并安裝所需的依賴項(xiàng)。
npm init -y npm i react react-dom react-scripts storeon @storeon/localstorage uuidv4
接下來(lái)就是在 index.js
文件中編寫父組件了。
index.js
這個(gè)文件負(fù)責(zé)渲染我們的筆記組件。首先導(dǎo)入所需的包。
import React from 'react' import { render } from 'react-dom'; function App() { return ( <> Hello! </> ); } const root = document.getElementById('root'); render(<App />, root);
接下來(lái)通過(guò)在 store.js
中編寫用于狀態(tài)的初始化和操作的代碼來(lái)構(gòu)建 store。
store.js
此文件負(fù)責(zé)處理應(yīng)用中的狀態(tài)和后續(xù)狀態(tài)管理操作。我們必須創(chuàng)建一個(gè)模塊來(lái)存儲(chǔ)狀態(tài)以及支持事件,以處理操作變更。
首先,從 Storeon 導(dǎo)入 createStoreon
方法和唯一隨機(jī)ID生成器 UUID。
createStoreon
方法負(fù)責(zé)將我們的 狀態(tài) 注冊(cè)到全局 store 。
import { createStoreon } from 'storeon'; import { v4 as uuidv4 } from 'uuid' import { persistState } from '@storeon/localstorage'; let note = store => {}
我們將狀態(tài)存儲(chǔ)在數(shù)組變量 notes
中,該變量包含以下格式的注釋:
{ id: 'note id', item: 'note item' },
接下來(lái),我們將用兩個(gè)注釋(在首次啟動(dòng)程序時(shí)會(huì)顯示)來(lái)初始化狀態(tài),從而首先填充注釋模塊。然后,定義狀態(tài)事件。
let note = store => { store.on('@init', () => ({ notes: [ { id: uuidv4(), item: 'Storeon is a React state management library and unlike other state management libraries that use Context, it utilizes an event-driven approach like Redux.' }, { id: uuidv4(), item: 'This is a really short note. I have begun to study the basic concepts of technical writing and I'\'m optimistic about becoming one of the best technical writers.' }, ] }); store.on('addNote', ({ notes }, note) => { return { notes: [...notes, { id: uuidv4(), item: note }], } }); store.on('deleteNote', ({ notes }, id) => ({ notes: notes.filter(note => note.id !== id), }); }
在上面的代碼中,我們定義了狀態(tài),并用兩個(gè)簡(jiǎn)短的注釋填充了狀態(tài),并定義了兩個(gè)事件和一個(gè)從 dispatch(event, data)
函數(shù)發(fā)出事件后將會(huì)執(zhí)行的回調(diào)函數(shù)。
在 addNote
事件中,我們返回添加了新 note 的更新后的狀態(tài)對(duì)象,在 deleteNote
事件中把 ID 傳遞給調(diào)度方法的 note 過(guò)濾掉。
最后,把模塊分配給可導(dǎo)出變量 store ,將其注冊(cè)為全局 store,以便稍后將其導(dǎo)入到上下文 provider 中,并將狀態(tài)存儲(chǔ)在 localStorage
中。
const store = createStoreon([ notes, // Store state in localStorage persistState(['notes']), ]); export default store;
接下來(lái),在 Notes.js
中編寫 Notes 應(yīng)用組件。
Notes.js
此文件包含 Notes 程序的組件。我們將從導(dǎo)入依賴項(xiàng)開(kāi)始。
import React from 'react'; import { useStoreon } from 'storeon/react';
接下來(lái),編寫組件。
const Notes = () => { const { dispatch, notes } = useStoreon('notes'); const [ value, setValue ] = React.useState(''); }
在上面的代碼的第二行中,useStoreon()
hook 的返回值設(shè)置為可破壞的對(duì)象。 useStoreon()
hook 使用模塊名稱作為其參數(shù),并返回狀態(tài)和調(diào)度方法以發(fā)出事件。
接下來(lái)定義在組件中發(fā)出狀態(tài)定義事件的方法 。
const Notes = () => { ... const deleteNote = id => { dispatch('deleteNote', id) }; const submit = () => { dispatch('addNote', value); setValue(''); }; const handleInput = e => { setValue(e.target.value); }; }
Let’s review the three methods we defined the above:
讓我們回顧一下上面定義的三種方法:
deleteNote(id)
– 此方法在觸發(fā)時(shí)調(diào)度 deleteNote
事件。
submit()
– 該方法通過(guò)傳遞輸入狀態(tài)的值來(lái)調(diào)度 addNote
事件,該狀態(tài)在 Notes
組件中本地定義。
handleInput()
– 此方法將本地狀態(tài)的值設(shè)置為用戶輸入。
Next, we’ll build the main interface of our app and export it.
接下來(lái),我們將構(gòu)建應(yīng)用程序的主界面并將其導(dǎo)出。
const Notes = () => { ... return ( <section> <header>Quick Notes</header> <div className='addNote'> <textarea onChange={handleInput} value={value} /> <button onClick={() => submit()}> Add A Note </button> </div> <ul> {notes.map(note => ( <li key={note.id}> <div className='todo'> <p>{note.item}</p> <button onClick={() => deleteNote(note.id)}>Delete note</button> </div> </li> ))} </ul> </section> ); }
這樣就構(gòu)成了我們的 Notes
組件。接下來(lái)為我們的應(yīng)用和 index.html
文件編寫樣式表。
index.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <link rel="stylesheet" href="style.css"> <title>Storeon Todo App</title> </head> <body> <div id="root"></div> </body> </html>
接下來(lái),填充我們的 style.css
文件。
style.css
* { box-sizing: border-box; margin: 0; padding: 0; } section { display: flex; justify-content: center; align-items: center; flex-direction: column; width: 300px; margin: auto; } header { text-align: center; font-size: 24px; line-height: 40px; } ul { display: block; } .todo { display: block; margin: 12px 0; width: 300px; padding: 16px; box-shadow: 0 8px 12px 0 rgba(0, 0, 0, 0.3); transition: 0.2s; word-break: break-word; } li { list-style-type: none; display: block; } textarea { border: 1px double; box-shadow: 1px 1px 1px #999; height: 100px; margin: 12px 0; width: 100%; padding: 5px 10px; } button { margin: 8px 0; border-radius: 5px; padding: 10px 25px; } .box:hover { box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2); }
現(xiàn)在我們已經(jīng)成功編寫了組件和樣式表,但是還沒(méi)有更新 index.js
中的父組件來(lái)渲染 Notes 組件。接下來(lái)讓我們渲染 Notes 組件。
index.js
要訪問(wèn)我們的全局 store,必須導(dǎo)入 store 和 Storeon store 上下文組件。我們還將導(dǎo)入 notes 組件來(lái)進(jìn)行渲染。
用以下代碼替換組件的內(nèi)容:
import React from 'react'; import { render } from 'react-dom'; import { StoreContext } from 'storeon/react'; import Notes from './Components/Notes'; import store from '../src/store'; function App() { return ( <> <StoreContext.Provider value={store}> <Notes /> </StoreContext.Provider> </> ); } const root = document.getElementById('root'); render(<App />, root);
在第 8-10 行,調(diào)用 store 上下文提供程序組件,并將 notes 組件作為使用者傳遞。store 上下文提供程序組件將全局 store 作為其上下文值。
接下來(lái)把 package.json
文件中的腳本部分編輯為以下內(nèi)容:
"scripts": { "start": "react-scripts start", }
然后運(yùn)行我們的程序:
npm run start
讓我們繼續(xù)添加和刪除注釋:
Storeon 與 Redux 有著相似的屬性,可以在 Redux DevTools 中可視化和監(jiān)視狀態(tài)的更改。為了可視化 Storeon 程序中的狀態(tài),我們將導(dǎo)入 devtools
包,并將其作為參數(shù)添加到我們 store.js
文件的 createStoreon()
方法中。
... import { storeonDevtools } from 'storeon/devtools'; ... const store = createStoreon([ ..., process.env.NODE_ENV !== 'production' && storeonDevtools, ]);
這是用 Redux DevTools 可視化狀態(tài)變化的演示:
感謝各位的閱讀!關(guān)于“React中使用事件驅(qū)動(dòng)進(jìn)行狀態(tài)管理的方法”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。