如何在 Async Redux Action 成功后转换到另一条路由
介绍
单页应用程序中的重定向可能有点棘手,尤其是使用 React 和 Redux 时。我们可以在组件本身或中间件中以编程方式进行重定向。在本指南中,我们将学习如何在异步操作成功时进行重定向。
有几种方法可以将用户重定向到另一个路由,包括history.push()方法和react-router中的<Redirect />组件。在本指南中,我们将使用 Redux 操作通过<Redirect />组件重定向用户。
在用户提交注册表后,我们将发送一项操作将用户重定向到主页。
Action Creator 和 Reducer
让我们从动作创建者和减速器开始。
ui.js
在ui.js文件中,我们将创建REDIRECT操作,并在其有效负载中传递重定向页面的链接。我添加了一个console.log()语句,以便在分派操作时更加明显。
export const REDIRECT = "REDIRECT";
// action creators
export const redirect = link => {
console.log("=== REDIRECT ACTION DISPATCHED ===");
return { type: REDIRECT, payload: link };
};
注册.js
在register.js文件中,我们将创建一个REGISTER动作,当用户单击注册表单的“提交”按钮时,该动作将被分派,并在有效负载中发送用户数据。
export const REGISTER = "REGISTER";
export const register = user => {
console.log("=== REGISTER ACTION DISPATCHED ===");
return {
type: REGISTER,
payload: user
};
};
api.js
所有与网络请求相关的操作,如API_REQUEST,API_SUCCESS和API_ERROR都将包含在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, data }) => {
return {
type: API_REQUEST,
meta: { url, method, data }
};
};
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
});
Reducer.js
Reducer相当简单;我们将把重定向链接存储在 store 中。我们不需要在这里添加用户的数据,因为它不会在我们的应用程序的任何组件中使用。
const reducer = (state = {}, action) => {
switch (action.type) {
case REDIRECT:
return { redirectTo: action.payload };
default:
return state;
}
};
export default reducer;
在下一节中,我们将开始编写注册表。
登记表格
在注册表单中,我们将有三个字段:姓名、电子邮件和密码。为了让 UI 美观整洁,我将使用material-ui,但您可以使用您选择的任何 UI 库。
// ..
<form>
<Typography variant="h5" style={{ marginBottom: 8 }}>
Create an account
</Typography>
<TextField
label="Name"
variant="outlined"
fullWidth
className="form-input"
value={name}
onChange={e => setName(e.target.value)}
/>
<TextField
label="Email"
variant="outlined"
fullWidth
className="form-input"
value={email}
onChange={e => setEmail(e.target.value)}
/>
<TextField
label="Password"
variant="outlined"
fullWidth
className="form-input"
type="password"
value={password}
onChange={e => setPassword(e.target.value)}
/>
<Button
variant="contained"
color="primary"
fullWidth
className="form-input"
size="large"
onClick={submitForm}
>
Register
</Button>
{(props.error || error) && (
<Alert severity="error" onClick={() => setError(null)}>
{props.error || error}
</Alert>
)}
</form>
// ..
我们将表单创建为一个功能组件,并使用useState钩子管理状态。
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [name, setName] = useState("");
const [error, setError] = useState("");
单击“提交”按钮时,我们将进行基本验证并分派REGISTER操作。
const submitForm = () => {
if (email === "" || password === "" || name === "") {
setError("Fields are required");
return;
}
props.register({ name, email, password });
};
从注册页面本身,我们将把用户重定向到主页。为此,我们将检查全局状态中是否有redirectTo属性,并根据该重定向,用户使用react-router中的<Redirect />组件。
if (props.redirectTo) {
return <Redirect to={props.redirectTo} />;
}
最后我们的注册页面将如下所示:
import React, { useState } from "react";
import { TextField, Typography, Button } from "@material-ui/core";
import { connect } from "react-redux";
import { register } from "../actions/register";
import MuiAlert from "@material-ui/lab/Alert";
import { Redirect } from "react-router";
function Alert(props) {
return <MuiAlert elevation={6} variant="filled" {...props} />;
}
export default connect(({ redirectTo }) => ({ redirectTo }), { register })(
props => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [name, setName] = useState("");
const [error, setError] = useState("");
const submitForm = () => {
if (email === "" || password === "" || name === "") {
setError("Fields are required");
return;
}
props.register({ email, password });
};
if (props.redirectTo) {
return <Redirect to={props.redirectTo} />;
}
return (
<form>
<Typography variant="h5" style={{ marginBottom: 8 }}>
Create an account
</Typography>
<TextField
label="Name"
variant="outlined"
fullWidth
className="form-input"
value={name}
onChange={e => setName(e.target.value)}
/>
<TextField
label="Email"
variant="outlined"
fullWidth
className="form-input"
value={email}
onChange={e => setEmail(e.target.value)}
/>
<TextField
label="Password"
variant="outlined"
fullWidth
className="form-input"
type="password"
value={password}
onChange={e => setPassword(e.target.value)}
/>
<Button
variant="contained"
color="primary"
fullWidth
className="form-input"
size="large"
onClick={submitForm}
>
Register
</Button>
{(props.error || error) && (
<Alert severity="error" onClick={() => setError(null)}>
{props.error || error}
</Alert>
)}
</form>
);
}
);
Redux 中间件
与之前的指南一样,我们将有两个中间件功能。第一个将处理网络请求,第二个将处理特定于应用程序的要求(在我们的例子中是注册)。
应用程序.js
在app.js文件中,我们将捕获REGISTER操作,使用apiRequest()操作创建器分派API_REQUEST操作,并将用户数据传递到其中。
import { apiRequest } from "../actions/api";
import { REGISTER } from "../actions/register";
const SERVER_URL = `https://61m46.sse.codesandbox.io`;
export const appMiddleware = () => next => action => {
next(action);
switch (action.type) {
case REGISTER: {
next(
apiRequest({
url: `${SERVER_URL}/register`,
method: "POST",
data: action.payload
})
);
break;
}
default:
<span class="hljs-keywor
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~