ReactJS - 使用Flux管理狀態



前端應用程式的一個重要功能是狀態管理。React 擁有自己的元件狀態管理技術。React狀態管理僅在元件級別起作用。即使元件之間存在父子關係(巢狀元件),一個元件的狀態也不會被另一個元件訪問。為了克服這個問題,有很多第三方狀態管理庫,例如redux、mobx等。

Flux是一種有效管理應用程式狀態的技術。Flux由Facebook引入,並在其Web應用程式中廣泛使用。Flux使用單向資料流模式來提供清晰的狀態管理。讓我們在本節中學習什麼是Flux以及如何在React中使用它。

使用Flux管理狀態

Flux使用單向資料流模式。它有四個不同的部分:

儲存(Store) -顧名思義,所有業務資料都儲存在儲存中。儲存執行兩個過程。

  • 儲存會透過從註冊的排程器收集資料來自行更新其資料。排程器向儲存提供資料和相關操作。

  • 資料更新後,儲存會發出更改資料事件以通知檢視資料已更改。檢視將監聽更改事件,並在收到更改事件後透過訪問儲存中的更新資料來更新其檢視。

操作(Action) -操作只是要處理的操作的表示,以及必要的資料。檢視將根據使用者互動建立包含必要資料的操作,並將其傳送到排程器。例如,以下提到的有效負載是由檢視(操作建立器)根據使用者互動建立的,用於新增使用者。

{
   actionType: "add",
   data: {
      name: "Peter"
   }
}

上述操作將傳遞給排程器,排程器會將資訊傳送給所有已註冊的儲存。儲存將相應地更新資料,並將更改事件傳送給所有已註冊的檢視。

排程器(Dispatcher) -排程器接收具有正確有效負載的操作,並將其傳送到所有已註冊的儲存以進行進一步處理。

檢視(View) -檢視根據使用者互動建立操作並將其傳送到排程器。它向儲存註冊以獲取更改,並在透過事件接收到更改後,將使用新資料更新自身。

為了使Flux有效工作,需要初始化一些內容,如下所示:

  • 應用程式應使用正確的操作及其回撥初始化排程器。

  • 儲存應初始化並向排程器註冊以接收資料更新。

  • 檢視應使用排程器和儲存初始化。檢視應註冊以監聽儲存更改(事件)。

Flux架構的工作流程如下:

  • 使用者互動並在檢視中觸發事件。

  • 檢視處理事件並根據使用者的操作建立操作。

  • 檢視將操作傳送到排程器。

  • 排程器將其釋出到所有已註冊的儲存。

  • 已註冊的儲存將收到帶有有效負載的操作。儲存將根據操作更新自身。

  • 儲存會向檢視發出更改事件。

  • 偵聽儲存更改的檢視將使用更新的資料更新前端。

Managing State Using Flux

應用Flux

讓我們建立一個新的React應用程式來學習如何在這一部分中應用Flux的概念。首先,使用以下命令建立一個新的React應用程式並啟動它。

create-react-app myapp
cd myapp
npm start

接下來,使用npm安裝Flux包,如下所示:

npm install flux --save

接下來,開啟App.css(src/App.css)並刪除所有CSS類。接下來,建立一個Flux排程器,Dispatcher(src/Flux/Dispatcher.js),如下所示:

import {Dispatcher} from "flux";
export default new Dispatcher();

在這裡,我們從Flux包建立了一個新的排程器。接下來,建立操作(和操作建立器),UserActions(src/Flux/UserActions.js),如下所示:

import dispatcher from "./Dispatcher";
export const USER_ACTIONS = {
   ADD: 'addUser'
};
export function addUser(userName) {
   dispatcher.dispatch({
      type: USER_ACTIONS.ADD,
      value: {
         name: userName
      }
   })
}

這裡:

  • USER_ACTIONS.ADD是一個常量,用於引用使用者的新增操作。

  • addUser()是用於建立操作以及使用者資料並將建立的操作分派到排程器的方法。

接下來,建立一個儲存,UserStore(src/Flux/UserStore.js),如下所示:

import dispatcher from "./Dispatcher";
import {EventEmitter} from "events";
import * as UserActions from "./UserActions";
class UserStore extends EventEmitter {
   constructor() {
      super();
      this.users = [];
   }
   handleActions(action) {
      switch (action.type) {
         case UserActions.USER_ACTIONS.ADD: {
            this.users.push(action.value);
            this.emit("storeUpdated");
            break;
         }
         default: {
         }
      }
   }
   getUsers() {
      return this.users;
   }
}
const userStore = new userStore();
dispatcher.register(userStore.handleActions.bind(userStore));
export default userStore;

這裡:

  • UserStore擴充套件自EventEmitter以發出更改。

  • handleActions從排程器檢索使用者詳細資訊並更新自身(this.users)。

  • handleActions發出儲存更新事件以通知檢視儲存已更新。

  • getUsers()方法將返回當前使用者列表資訊。

接下來,建立一個使用者輸入元件,UserInput元件以獲取新的使用者資訊,如下所示:

import React from "react";
import * as UserActions from "./UserActions";
export default class ButtonComponent extends React.Component {
   constructor(props) {
      super(props);
      this.state = {
         username: ''
      }
   }
   onButtonClick = () => {
      UserActions.addUser(this.state.username)
   };
   render() {
      return (
         <div>
            <input name="username" onChange={(e) => this.setState({username: e.target.value})}/>
            <button onClick={() => this.onButtonClick()}>Add user</button>
         </div>
      );
   }
}

這裡:

  • 建立一個輸入元素以從使用者獲取新使用者資料。

  • 新增一個按鈕以將使用者資訊提交到UserActions的addUser()方法

  • addUser將更新使用者資料並將其與正確的操作型別一起傳送到排程器。排程器將使用操作型別呼叫儲存。儲存將更新使用者列表並通知所有已註冊的檢視。

接下來,建立一個使用者列表元件,UserList元件以顯示儲存中可用的使用者,如下所示:

import React from "react";
import UserStore from "./UserStore";
export default class UserList extends React.Component {
   constructor(props) {
      super(props);
      this.state = {
         users: UserStore.getUsers()
      }
   }
   componentDidMount() {
      UserStore.on("storeUpdated", this.updateUserList);
   }
   componentWillUnmount() {
      UserStore.removeListener("storeUpdated", this.updateUserList);
   }
   updateUserList = () => {
      this.setState({users: UserStore.getUsers()})
   };
   render() {
      return (
         <ul>{
            this.state.users && this.state.users.length > 0 &&
            this.state.users.map((items) => <li>{items.name}</li>)
         }
         </ul>
      );
   }
}

這裡:

  • componentDidMount透過UserStore.on方法註冊儲存事件(storeUpdated)。

  • componentWillUnmount透過UserStore.removeListener方法登出儲存事件(storeUpdated)。

  • updateUserList從儲存獲取最新的使用者資料並更新其自身儲存。

  • render方法從其狀態(this.state.users)渲染使用者列表。

接下來,開啟App元件(src/App.js),並使用UserInputUserList元件,如下所示:

import './App.css'
import React, { Suspense, lazy } from 'react';
import UserInput from './Flux/UserInput';
import UserList from './Flux/UserList';
function App() {
   return (
      <div className="container">
         <div style={{ padding: "10px" }}>
            <div>
               <UserInput />
               <UserList />
            </div>
         </div>
      </div>
   );
}
export default App;

這裡:

  • UserInput將用於從使用者獲取資訊。

  • UserList將從儲存獲取最新的使用者列表並渲染它。

最後,在瀏覽器中開啟應用程式並檢查最終結果。最初,使用者列表將為空。一旦使用者輸入使用者名稱並提交,以下列表將顯示更新後的使用者列表,如下所示:

Applying Flux

總結

Flux是一種簡單、單向的狀態管理模式,適用於React應用程式。它有助於降低React應用程式的複雜性。它以透明的方式透過排程器連線檢視和儲存。React社群增強了Flux模式併發布了許多成熟的狀態管理庫(如redux),這些庫功能更強大且易於使用。

廣告

© . All rights reserved.