溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

怎么在React中進(jìn)行事件驅(qū)動(dòng)的狀態(tài)管理

發(fā)布時(shí)間:2021-10-28 14:28:11 來源:億速云 閱讀:159 作者:iii 欄目:web開發(fā)

本篇內(nèi)容主要講解“怎么在React中進(jìn)行事件驅(qū)動(dòng)的狀態(tài)管理”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“怎么在React中進(jìn)行事件驅(qū)動(dòng)的狀態(tài)管理”吧!

Store

store 是在應(yīng)用程序狀態(tài)下存儲(chǔ)的數(shù)據(jù)的集合。它是通過從 Storeon 庫導(dǎo)入的 createStoreon() 函數(shù)創(chuàng)建的。

createStoreon() 函數(shù)接受模塊列表,其中每個(gè)模塊都是一個(gè)接受 store 參數(shù)并綁定其事件監(jiān)聽器的函數(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 是模塊化的,也就是說,它們是獨(dú)立定義的,并且沒有被綁定到 Hook 或組件。每個(gè)狀態(tài)及其操作方法均在被稱為模塊的函數(shù)中定義。這些模塊被傳遞到 createStoreon() 函數(shù)中,然后將其注冊(cè)為全局 store。

store 有三種方法:

  1. store.get() – 用于檢索狀態(tài)中的當(dāng)前數(shù)據(jù)。

  2. store.on(event, callback) – 用于把事件偵聽器注冊(cè)到指定的事件名稱。

  3. store.dispatch(event, data) – 用于發(fā)出事件,并根據(jù)定義的事件要求將可選數(shù)據(jù)傳遞進(jìn)來。

Events

Storeon 是基于事件的狀態(tài)管理庫,狀態(tài)更改由狀態(tài)模塊中定義的事件發(fā)出。Storeon 中有三個(gè)內(nèi)置事件,它們以 @ 開頭。其他事件不帶 @ 前綴定義。三個(gè)內(nèi)置事件是:

  1. @init – 在應(yīng)用加載時(shí)觸發(fā)此事件。它用于設(shè)置應(yīng)用的初始狀態(tài),并執(zhí)行傳遞給它的回調(diào)中的所有內(nèi)容。

  2. @dispatch – 此事件在每個(gè)新動(dòng)作上觸發(fā)。這對(duì)于調(diào)試很有用。

  3. @changed – 當(dāng)應(yīng)用狀態(tài)發(fā)生更改時(shí),將觸發(fā)此事件。

注意:store.on(event,callback) 用于在我們的模塊中添加事件監(jiān)聽器。

演示程序

為了演示在 Storeon 中如何執(zhí)行應(yīng)用程序狀態(tài)操作,我們將構(gòu)建一個(gè)簡單的 notes 程序。還會(huì)用 Storeon 的另一個(gè)軟件包把狀態(tài)數(shù)據(jù)保存在 localStorage 中。

假設(shè)你具有 JavaScript 和 React 的基本知識(shí)。你可以在https://github.com/Youngestdev/storeon-app 上找到本文中使用的代碼。

設(shè)置

在深入探討之前,讓我們先勾勒出 Notes 程序所需的項(xiàng)目結(jié)構(gòu)和依賴項(xiàng)的安裝。從創(chuàng)建項(xiàng)目文件夾開始。

mkdir storeon-app && cd storeon-app mkdir {src,public,src/Components} touch public/{index.html, style.css} && touch src/{index,store,Components/Notes}.js

接下來,初始化目錄并安裝所需的依賴項(xiàng)。

npm init -y npm i react react-dom react-scripts storeon @storeon/localstorage uuidv4

接下來就是在 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);

接下來通過在 store.js 中編寫用于狀態(tài)的初始化和操作的代碼來構(gòu)建 store。

`store.js`

此文件負(fù)責(zé)處理應(yīng)用中的狀態(tài)和后續(xù)狀態(tài)管理操作。我們必須創(chuàng)建一個(gè)模塊來存儲(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' },

接下來,我們將用兩個(gè)注釋(在首次啟動(dòng)程序時(shí)會(huì)顯示)來初始化狀態(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) => ({  });16}

在上面的代碼中,我們定義了狀態(tài),并用兩個(gè)簡短的注釋填充了狀態(tài),并定義了兩個(gè)事件和一個(gè)從 dispatch(event, data) 函數(shù)發(fā)出事件后將會(huì)執(zhí)行的回調(diào)函數(shù)。

在 addNote 事件中,我們返回添加了新 note 的更新后的狀態(tài)對(duì)象,在 deleteNote 事件中把 ID 傳遞給調(diào)度方法的 note 過濾掉。

最后,把模塊分配給可導(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;

接下來,在 Notes.js 中編寫 Notes 應(yīng)用組件。

`Notes.js`

此文件包含 Notes 程序的組件。我們將從導(dǎo)入依賴項(xiàng)開始。

import React from 'react'; import { useStoreon } from 'storeon/react';

接下來,編寫組件。

const Notes = () => {   const { dispatch, notes } = useStoreon('notes');  const [ value, setValue ] = React.useState('');  }

在上面的代碼的第二行中,useStoreon() hook 的返回值設(shè)置為可破壞的對(duì)象。useStoreon() hook 使用模塊名稱作為其參數(shù),并返回狀態(tài)和調(diào)度方法以發(fā)出事件。

接下來定義在組件中發(fā)出狀態(tài)定義事件的方法 。

const Notes = () => { ...   const deleteNote = id => {     dispatch('deleteNote', id)  };  const submit = () => {    dispatch('addNote', value);   setValue('');  };  const handleInput = e => {    setValue(e.target.value);  };}

讓我們回顧一下上面定義的三種方法:

  1. deleteNote(id) &ndash; 此方法在觸發(fā)時(shí)調(diào)度deleteNote事件。

  2. submit() &ndash; 該方法通過傳遞輸入狀態(tài)的值來調(diào)度addNote事件,該狀態(tài)在Notes組件中本地定義。

  3. handleInput() &ndash; 此方法將本地狀態(tài)的值設(shè)置為用戶輸入。

Next, we&rsquo;ll build the main interface of our app and export it.接下來,我們將構(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>   );24}25

這樣就構(gòu)成了我們的Notes組件。接下來為我們的應(yīng)用和index.html文件編寫樣式表。

`index.html`

<!DOCTYPE html> <html lang="en"> <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>

接下來,填充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); }

運(yùn)行

現(xiàn)在我們已經(jīng)成功編寫了組件和樣式表,但是還沒有更新 index.js 中的父組件來渲染 Notes 組件。接下來讓我們渲染 Notes 組件。

`index.js`

要訪問我們的全局 store,必須導(dǎo)入 store 和 Storeon store 上下文組件。我們還將導(dǎo)入 notes 組件來進(jìn)行渲染。

用以下代碼替換組件的內(nèi)容:

 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 作為其上下文值。

接下來把 package.json 文件中的腳本部分編輯為以下內(nèi)容:

"scripts": {   "start": "react-scripts start", }

然后運(yùn)行我們的程序:

npm run start

讓我們繼續(xù)添加和刪除注釋:

怎么在React中進(jìn)行事件驅(qū)動(dòng)的狀態(tài)管理

Storeon devtools

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)變化的演示:

怎么在React中進(jìn)行事件驅(qū)動(dòng)的狀態(tài)管理

到此,相信大家對(duì)“怎么在React中進(jìn)行事件驅(qū)動(dòng)的狀態(tài)管理”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI