[英]React dispatch going in the infinite loop
While making a post request my request is going in a loop.在发出发布请求时,我的请求正在循环中。 Not sure why it's happening.
不知道为什么会这样。 Its happening at the handleSubmit of the form.
它发生在表单的句柄提交处。 I referred few question from stackoverflow but it did not helped me.
我从stackoverflow提到了几个问题,但它没有帮助我。 Still looking for a solution.
仍在寻找解决方案。 Dammm its Ruined my SUNDAY.
Dammm 它毁了我的星期天。
import React, { useState } from "react";
import { Link } from "react-router-dom";
import { FORGOT_PASSWORD } from "../../redux/types";
import { useDispatch, useSelector } from "react-redux";
import AuthLayout from "../../layouts/Auth";
export default function ForgotPassword() {
const dispatch = useDispatch();
const [email, setEmail] = useState("");
const handleSubmit = async (e) => {
console.log(email,'---get email')
e.preventDefault();
const payload = { email };
//loginUser(payload)
console.log(payload,'=====')
dispatch({ type: FORGOT_PASSWORD, payload });
};
return (
<AuthLayout>
<div className="container mx-auto px-4 h-full">
<div className="flex content-center items-center justify-center h-full">
<div className="w-full lg:w-4/12 px-4">
<div className="relative flex flex-col min-w-0 break-words w-full mb-6 shadow-lg rounded-lg bg-blueGray-200 border-0">
<div className="rounded-t mb-0 px-6 py-6">
<div className="text-blueGray-400 text-center mb-3 font-bold">
<center>Reset your password </center>
</div>
<hr className="mt-6 border-b-1 border-blueGray-300" />
</div>
<div className="flex-auto px-4 lg:px-10 py-10 pt-0">
<form onSubmit={handleSubmit}>
<div className="relative w-full mb-3">
<label
className="block uppercase text-blueGray-600 text-xs font-bold mb-2"
htmlFor="grid-password"
>
Email
</label>
<input
value={email}
onChange={(e) => setEmail(e.target.value)}
type="email"
required
className="border-0 px-3 py-3 placeholder-blueGray-300 text-blueGray-600 bg-white rounded text-sm shadow focus:outline-none focus:ring w-full ease-linear transition-all duration-150"
placeholder="Email"
/>
</div>
<div className="text-center mt-6">
<button
className="bg-blueGray-800 text-white active:bg-blueGray-600 text-sm font-bold uppercase px-6 py-3 rounded shadow hover:shadow-lg outline-none focus:outline-none mr-1 mb-1 w-full ease-linear transition-all duration-150"
type="submit"
>
{/* {loading ? "Sending email..." : "Reset Password"} */} Reset Password
</button>
</div>
</form>
</div>
</div>
<div className="flex flex-wrap mt-6 relative">
<div className="w-1/2">
<Link to="/auth/forgot-password" className="text-blueGray-200">
Login?
</Link>
</div>
<div className="w-1/2 text-right">
<Link to="/auth/register" className="text-blueGray-200">
Create new account
</Link>
</div>
</div>
</div>
</div>
</div>
</AuthLayout>
);
}
This is my Redux looks like这是我的 Redux 看起来像
import { LOGIN, REGISTER, LOGOUT, FORGOT_PASSWORD } from "../types";
const initialState = {};
const auth = (state = initialState, { type, payload }) => {
switch (type) {
case LOGIN:
return { ...state, ...payload };
case REGISTER:
return { ...state, ...payload };
case LOGOUT:
return { ...state, ...payload };
case FORGOT_PASSWORD:
return { ...state, ...payload };
default:
return state;
}
};
export default auth;
And this is how my SAGA looks like这就是我的 SAGA 的样子
export function* forgotPassword({ payload }) {
yield put({ type: FORGOT_PASSWORD, payload: { loading: true } });
try {
const { status } = yield authService.forgotPassword(payload);
if (status === 204) {
const key = 'updatable';
// notification.success({ message: "Logged in successfully" });
message.loading({ content: 'Loading...', key });
message.success({ content: 'Reset password link sent to your email!', key, duration: 4 });
//window.location.replace("/dashboard");
} else yield put({ type: FORGOT_PASSWORD, payload: { loading: false } });
} catch (error) {
yield put({ type: FORGOT_PASSWORD, payload: { loading: false } });
}
}
The issue I when I submit that form it just goes in loop.我提交该表单时的问题只是循环。 INFINITE LOOP
无限循环
EDIT-编辑-
After debugging I see it keep looping at SAGA and SERVICE CALL [JUST IN CASE THE API I AM CALLING HAS RESPONSE SUCCESS CODE 204]调试后,我看到它一直在 SAGA 和 SERVICE CALL 处循环 [仅以防万一我正在调用的 API 有响应成功代码 204]
// THIS IS SERVICE CALL
const userInstance = axios.create({
baseURL: 'http://localhost:3005/v1/',
headers: { "Content-Type": "application/json" },
timeout: 10000,
responseType: "json",
validateStatus: (status) => status < 400,
});
// BELOW IS THE API call I am making
async function forgotPassword(payload) {
return userInstance
.post("/auth/forgot-password", payload)
.then((response) => {
if (response) {
return response;
}
return false;
})
.catch((err) => console.log(err));
}
And this is my SAGA FUCNTION这就是我的 SAGA 功能
export function* forgotPassword({ payload }) {
console.log('======AT SAGA', payload);
yield put({ type: FORGOT_PASSWORD, payload: payload });
try {
// here below line the SERVICE function for API call is called
const { status } = yield forgotPassword(payload);
if (status === 204) {
const key = 'updatable';
// notification.success({ message: "Logged in successfully" });
message.loading({ content: 'Loading...', key });
message.success({ content: 'Reset password link sent to your email!', key, duration: 4 });
//window.location.replace("/dashboard");
} else yield put({ type: FORGOT_PASSWORD, payload: { loading: false } });
} catch (error) {
yield put({ type: FORGOT_PASSWORD, payload: { loading: false } });
}
}
//EXPORT ALL TO ROOT
export default function* rootSaga() {
yield all([
takeEvery(LOGIN, login),
takeEvery(REGISTER, register),
takeEvery(LOGOUT, logoutUser),
]);
yield all([takeEvery(FORGOT_PASSWORD, forgotPassword)]);
}
SO AFTER DEBUGGING IT JUST KEEP LOOPING INFINITE - FROM SAGA FUNCTION TO THE SERVICE CALL FUNCTION WHERE ITs been called at SAGA.所以在调试后它只是保持无限循环 - 从 SAGA FUNCTION 到服务呼叫 FUNCTION,它在 SAGA 被调用。
I'm pretty sure it's because you use the action type "FORGOT_PASSWORD"
for triggering both state update in reducer and the saga function.我很确定这是因为您使用操作类型
"FORGOT_PASSWORD"
来触发减速器中的 state 更新和传奇 function。
You said you've tried my solution.你说你试过我的解决方案。 But I doubt you're still missing some points.
但我怀疑你仍然遗漏了一些观点。 So I'mma post the solution again in full details.
所以我会再次详细发布解决方案。
My reasoning:我的推理:
put
in saga function is effectively dispatch
in redux's term. put
saga function 在 redux 的术语中是有效的dispatch
。dispatch({ type: "FORGOT_PASSWORD" })
from handleSubmit
to trigger initial run of saga, the action first arrives at the redux storehandleSubmit
dispatch({ type: "FORGOT_PASSWORD" })
触发saga的初始运行,action首先到达redux storetakeEvery("FORGOT_PASSWORD", forgotPassword)
, it's now routed to forgotPassword
saga function takeEvery("FORGOT_PASSWORD", forgotPassword)
了这个动作,现在它被路由到了forgotPassword
saga functionforgotPassword
run some side-effects, and eventually you wanna tell the redux reducer to update the state. forgotPassword
运行了一些副作用,最终你想告诉 redux 减速器更新 state。 So you put({ type: "FORGOT_PASSWORD" })
wishing it would reach the reducer.put({ type: "FORGOT_PASSWORD" })
希望它能到达减速器。forgotPassword
, now you're in a infinite loop.forgotPassword
,现在您处于无限循环中。 Notice throughout the above explanation I always use string literals to present action types?请注意在上面的解释中我总是使用字符串文字来表示动作类型?
"FORGOT_PASSWORD"
with double quotes. "FORGOT_PASSWORD"
带双引号。
You said in the comment你在评论里说
those are just CONSTANTS so I think does not matter
这些只是常数,所以我认为没关系
Obviously you missed the crucial point.显然你错过了关键点。 Off course I don't mean to change the constants variable name, I mean change the action types' string literal .
当然,我并不是要更改常量变量名称,而是要更改操作类型的string literal 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.