如何在离开 React 中的组件时中止请求
介绍
React-Redux 是比较流行的库组合之一。它的优点之一是非常灵活,我们可以独立于库编写代码。这种灵活性还意味着我们应该涵盖库代码中可能未包含的所有边缘情况。
其中一个极端情况是,当用户离开当前页面组件时中止网络请求。如果我们不中止或取消请求,则可能会对性能造成很大影响,尤其是当用户使用低端设备或连接速度较慢时。
在本指南中,我们将学习如何处理这种场景 b 在 Redux 中创建自定义中间件来管理网络请求。
设置项目
我们将运行create-react-app 命令来创建我们的 React 项目。
create-react-app cancel-demo
接下来,我们将安装所需的 npm 模块。
npm i react-redux redux axios react-router-dom
现在你应该熟悉axios和react-router。axios是一个用于处理网络请求的 HTTP 库,而react -router是一个用于单页 React 应用程序的路由解决方案。
设置基本组件
我们将创建两条路线: Home 和 Search 。
<Home />组件将是一个包含一些文本的简单组件,在<Search />组件中,我们将创建一个搜索输入并将其连接到 Redux 以发出 API 请求。对于此演示,我将使用 Pixabay API;您也可以选择任何其他公共 API。
Home.js
import React from "react";
export default props => (
<div>
<p>This is the Home Page.</p>
<p>Go to Search Page and search some images.</p>
</div>
);
搜索.js
在<Search />组件中,我们将在状态中存储搜索词,并在搜索提交时,我们将分派操作来搜索图像。所有动作创建者将在下一节中显示。
import React, { Component } from "react";
import { connect } from "react-redux";
import { search } from "./actions/search";
class Search extends Component {
constructor(props) {
super(props);
this.state = {
searchTerm: "",
images: []
};
}
render() {
return (
<div>
<input
value={this.state.searchTerm}
onChange={e => this.setState({ searchTerm: e.target.value })}
/>
<button onClick={() => this.props.search(this.state.searchTerm)}>
Search
</button>
</div>
);
}
}
export default connect(null, {
search
})(Search);
将 React-Router 连接到 Redux Store
现在,让我们将react-router连接到redux store。Redux 将成为应用程序数据的唯一真实点,而 React Router 将成为 URL 的唯一真实点。
我们将从react-router-dom导入BrowserRouter、Switch和Route。
< BrowserRouter />使用 HTML5 History API 使 UI 与 URL 保持同步。
<Route />组件是react-router生态系统中最关键的组件。它根据当前的 URL 路径呈现 UI。
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import { Provider } from "react-redux";
import { createStore } from "redux";
import reducer from "./reducer";
import Home from "./Home";
import Search from "./Search";
import Navbar from "./Navbar";
import { appMiddleware } from "./middlewares/app";
import { apiMiddleware } from "./middlewares/core";
const store = createStore(reducer);
function App() {
return (
<Provider store={store}>
<Router>
<div>
<Navbar />
<Switch>
<Route path="/search">
<Search />
</Route>
<Route path="/" default>
<Home />
</Route>
</Switch>
</div>
</Router>
</Provider>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
编写动作创建者
动作创建器是一个创建动作的函数。用更专业的术语来说,它返回一个包含类型属性和其他有效负载数据的动作对象。
因此,在我们的示例中,我们将把动作创建器分成 3 个文件:api.js、ui.js和search.js。在api.js中,我们将包括所有为网络请求调度动作的动作创建器;在ui.js中,我们将只有一个动作创建器,其唯一目的是将加载器状态设置为 true 或 false;在search.js中,动作创建器将调度动作来修改搜索结果。
api.js
// action types
export const API_REQUEST = "API_REQUEST";
export const API_SUCCESS = "API_SUCCESS";
export const API_ERROR = "API_ERROR";
export const CANCEL_API_REQUEST = "CANCEL_API_REQUEST";
// action creators
export const apiRequest = ({ url, method }) => {
return {
type: API_REQUEST,
meta: { url, method }
};
};
export const cancelApiRequest = () => {
return {
type: CANCEL_API_REQUEST
};
};
export const apiSuccess = ({ response }) => ({
type: API_SUCCESS,
payload: response
});
export const apiError = ({ error }) => ({
type: API_ERROR,
payload: error
});
ui.js
export const SET_LOADER = "SET_LOADER";
export const setLoader = ({ state }) => ({
type: SET_LOADER,
payload: state
});
搜索.js
export const SEARCH = "SEARCH";
export const CANCEL_SEARCH = "CANCEL_SEARCH";
export const search = term => {
return {
type: SEARCH,
payload: term
};
};
export const cancelSearch = () => {
return {
type: CANCEL_SEARCH
};
};
编写自定义 Redux 中间件
当我们学习如何编写 Redux 中间件时,这将是一个有趣的部分。
Redux 中间件
Redux 中间件提供了一个接口,通过该接口,我们可以修改已分派的操作并与其交互,这些操作在到达 Redux 存储之前。Redux 中间件可用于记录操作、报告错误、发出异步请求等。中间件的另一个重要功能是它们可以分派新操作。我们将在我们的用例中更深入地探讨这种模式。
在进一步了解细节之前,我们先来看看如何创建中间件。
基本的中间件功能接收动作并以某种方式与其交互。
const middlewareFunction = action => {
// ...
};
对于中间件函数来说,要分派中间件链中的下一个动作,由于 redux 应用程序可以有任意数量的中间件,因此应该将其包装在另一个函数中,该函数接收下一个分派参数。
const wrappedMiddlewareFunction = next => {
const middlewareFunction = action => {
// ...
};
return middlewareFunction;
};
简化上面的代码片段,我们得到,
const middlewareFunction = next => action => {
// ...
};
此外,中间件函数还从redux的applyMiddleware函数接收了 store 的副本,即伪 store 。同样,这是通过包装函数实现的。因此,中间件函数的完整模板如下所示。
const middlewareFunction = store => next => action => {
// ...
};
如果我们不使用操作来调用下一个方法,那么控制将无法到达下一个中间件函数。
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~