ReactJS - 使用 Flux 管理状态



前端应用程序的一个重要特性是状态管理。React 的组件有自己的状态管理技术。React 状态管理仅在组件级别工作。即使组件处于父/子关系(嵌套组件),也不会在另一个组件中访问组件的状态。为了克服这个问题,有很多第三方状态管理库,比如 redux。mobx的。等。

Flux 是有效管理应用程序状态的技术之一。Flux 由 Facebook 推出,并在其 Web 应用程序中广泛使用它。Flux 使用单向数据流模式来提供清晰的状态管理。在本章中,让我们了解什么是通量以及如何使用它。

使用 Flux 管理状态

Flux 使用单向数据流模式。它有四个不同的部分,

商店 - 顾名思义,所有业务数据都存储在商店中。商店做两个过程。

  • 商店将通过从已注册的调度员处收集数据来自行更新其数据。Dispatcher 为存储提供数据和相关操作。
  • 数据更新后,存储会发出更改数据事件,以通知视图数据已更改。View 将侦听更改事件,并在收到更改事件后通过访问存储中的更新数据来更新其视图。

动作 - 动作只是用必要的数据处理的动作的表示。View 将根据用户交互使用必要数据创建操作,并将其发送到调度员。例如,下面提到的负载是由视图(动作创建者)根据用户交互创建的,以添加用户。


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

上述操作将被传递给调度员,调度员会将信息发送到所有已注册的商店。Store 将相应地更新数据,并将更改事件发送到在其注册的所有视图。

Dispatcher − Dispatcher 接收具有适当有效负载的操作,并将其发送到所有已注册的存储区进行进一步处理。

视图 - 视图根据用户交互创建操作,并将其发送到调度程序。它向商店注册以获取更改,一旦通过事件接收到更改,它将使用新数据进行自我更新。

为了通量的有效工作,需要初始化的东西很少,如下所示:

  • Dispatcher 应由应用程序使用适当的操作及其回调进行初始化。
  • 应初始化存储并将其注册到调度程序以接收数据更新。
  • 应使用调度程序和存储初始化视图。应注册视图以侦听商店更改(事件)。

flux 架构的工作流程如下:

  • 用户在视图中交互并触发事件。
  • View 处理事件并根据用户的操作创建操作。
  • 查看将操作发送到调度员。
  • Dispatcher 将操作发布到在其注册的所有商店,
  • 已注册的商店将接收带有有效负载的操作。商店将根据操作进行自我更新。
  • 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,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 将更新用户数据,并以正确的操作类型将其发送给调度员。Dispatcher 将调用具有操作类型的存储。商店将更新用户列表并通知在其注册的所有视图。

接下来,创建一个用户列表组件,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),并使用 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),这些库功能更强大,使用起来更方便。