ReactJS - 使用 Flux 管理状态
前端应用程序的一个重要特性是状态管理。React 对其组件有自己的状态管理技术。React 状态管理仅在组件级别工作。即使组件处于父/子关系(嵌套组件),另一个组件也不会访问组件的状态。为了解决这个问题,有很多第三方状态管理库,如 redux、mobx 等,
Flux 是有效管理应用程序状态的技术之一。Flux 由 Facebook 引入,并在其 Web 应用程序中广泛使用。Flux 使用单向数据流模式来提供清晰的状态管理。让我们在本章中了解什么是 flux 以及如何使用它。
使用 Flux 管理状态
Flux 使用单向数据流模式。它有四个不同的部分,
Store −顾名思义,所有业务数据都存储在 store 中。Store 执行两个过程。
Store 将通过从注册的调度程序收集数据来自行更新其数据。调度程序为 store 提供数据和相关操作。
一旦数据更新,store 就会发出一个更改数据事件来通知视图数据已更改。View 将监听更改事件,并在收到更改事件后通过访问来自 store 的更新数据来更新其视图。
Action − Action 只是要处理的操作的表示,其中包含必要的数据。View 将根据用户交互创建一个包含必要数据的操作并将其发送给调度程序。例如,下面提到的有效负载是由视图(操作创建者)根据用户交互创建的,用于添加用户。
{
actionType: "add",
data: {
name: "Peter"
}
}
上述操作将传递给调度程序,调度程序将信息发送给所有已注册的商店。商店将相应地更新数据,并将更改事件发送给所有已注册的视图。
调度程序 − 调度程序接收具有适当负载的操作,并将其发送给所有已注册的商店进行进一步处理。
视图 − 视图根据用户交互创建操作并将其发送给调度程序。它向 store 注册以获取更改,一旦通过事件接收到更改,它就会使用新数据更新自身。
为了 flux 的有效工作,需要初始化一些东西,如下所示 −
应用程序应使用适当的操作及其回调初始化 Dispatcher。
应初始化 Store 并向 dispatcher 注册以接收数据更新。
应使用 dispatcher 和 store 初始化视图。视图应该注册以监听存储更改(事件)。
flux 架构的工作流程如下 −
用户在视图中交互并触发事件。
视图处理事件并根据用户的操作创建操作。
视图将操作发送给调度程序。
调度程序将操作发布到所有向其注册的存储,
已注册的存储将接收带有有效负载的操作。 Store 将根据操作进行自我更新。
Store 将向视图发出更改事件。
监听 store 更改的视图将使用更新的数据更新前端。
应用 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方法注册store事件(storeUpdated)。
componentWillUnmount通过UserStore.removeListener方法取消注册store事件(storeUpdated)。
updateUserList从store获取最新的用户数据并更新其自己的store。
render方法从其状态(this.state.users)呈现用户列表。
接下来,打开App组件(src/App.js),并使用UserInput和UserList组件,如下所示 −
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 将从存储中获取最新的用户列表并呈现它。
最后,在浏览器中打开应用程序并检查最终结果。最初,用户列表将为空。一旦用户输入用户名并提交,下面的列表将显示更新的用户列表,如下所示 −
摘要
Flux 是 React 应用程序的简单、单向状态管理模式。它有助于降低 React 应用程序的复杂性。它以透明的方式通过调度程序连接视图和存储。 React 社区对 flux 模式进行了增强,并发布了许多成熟的状态管理库(如 redux),功能更加强大,使用更加方便。

