首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在成功登录redux进入redux的redux中后重定向到仪表板上?

如何在成功登录redux进入redux的redux中后重定向到仪表板上?
EN

Stack Overflow用户
提问于 2022-10-03 14:27:26
回答 1查看 160关注 0票数 0

我在react js中创建了登录页面,在节点js中创建了api。我试图使用电子邮件和密码登录使用redux。

登录页

代码语言:javascript
复制
    const Login = () => {

  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const dispatch = useDispatch();
  const navigate = useNavigate();
  const { user, isError, isSuccess, isLoading, message } = useSelector(
    (state) => state.auth
  );

  useEffect(() => {
    if (user || isSuccess) {
      navigate("/dashboard");
    }
    dispatch(reset());
  }, [user, isSuccess, dispatch, navigate]);

  const Auth = (e) => {
    e.preventDefault();
    dispatch(LoginUser({ email, password }));
  };

  return (
    <div className="wrapper">
        <main className="authentication-content">
        <div className="container-fluid">
        <div className="authentication-card">
            <div className="card shadow rounded-0 overflow-hidden">
            <div className="row g-0">
                <div className="col-lg-6 bg-login d-flex align-items-center justify-content-center">
                <img src="assets/images/error/login-img.jpg" className="img-fluid" alt=""/>
                </div>
                <div className="col-lg-6">
                <div className="card-body p-4 p-sm-5">
                    <h5 className="card-title">Sign In</h5>
                    <p className="card-text mb-5">See your growth and get consulting support!</p>
                    <form onSubmit={Auth} className="form-body">
                    {isError && <p className="has-text-centered">{message}</p>}
                        <div className="row g-3">
                        <div className="col-12">
                            <label htmlFor="inputEmailAddress" className="form-label">Email Address</label>
                            <div className="ms-auto position-relative">
                            <div className="position-absolute top-50 translate-middle-y search-icon px-3"><i className="bi bi-envelope-fill"></i></div>
                            <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} className="form-control radius-30 ps-5" id="inputEmailAddress" placeholder="Email Address"/>
                            </div>
                        </div>
                        <div className="col-12">
                            <label htmlFor="inputChoosePassword" className="form-label">Enter Password</label>
                            <div className="ms-auto position-relative">
                            <div className="position-absolute top-50 translate-middle-y search-icon px-3"><i className="bi bi-lock-fill"></i></div>
                            <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} className="form-control radius-30 ps-5" id="inputChoosePassword" placeholder="Enter Password"/>
                            </div>
                        </div>
                        <div className="col-6">
                            <div className="form-check form-switch">
                            <input className="form-check-input" type="checkbox" id="flexSwitchCheckChecked" />
                            <label className="form-check-label" htmlFor="flexSwitchCheckChecked">Remember Me</label>
                            </div>
                        </div>
                        <div className="col-6 text-end">    <a href="authentication-forgot-password.html">Forgot Password ?</a>
                        </div>
                        <div className="col-12">
                            <div className="d-grid">
                            <button type="submit" className="btn btn-primary radius-30">{isLoading ? "Loading..." : "Sign In"}</button>
                            </div>
                        </div>
                        </div>
                    </form>
                </div>
                </div>
            </div>
            </div>
        </div>
        </div>
        </main>
    </div>
  )
}

export default Login;

在呈现登录页面时,它在nullfalse中以userisSuccess显示。当我点击Sign In按钮。它在一秒内显示仪表板,然后重定向到登录页面,并在userisSuccess中显示isSuccess。当我点击5到10次,然后一旦它显示响应,并坚持在仪表板上。

AuthSlice文件

代码语言:javascript
复制
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import axios from "axios";

const initialState = {
    user: null,
    isError: false,
    isSuccess: false,
    isLoading: false,
    message: ""
}

export const LoginUser = createAsyncThunk("user/LoginUser", async(user, thunkAPI) => {
    try {
        const response = await axios.post('http://localhost:5001/login', {
            email: user.email,
            password: user.password
        });
        return response.data;
    } catch (error) {
        if(error.response){
            const message = error.response.data.msg;
            return thunkAPI.rejectWithValue(message);
        }
    }
});

export const getMe = createAsyncThunk("user/getMe", async(_, thunkAPI) => {
    try {
        const response = await axios.get('http://localhost:5001/me');
        return response.data;
    } catch (error) {
        if(error.response){
            const message = error.response.data.msg;
            return thunkAPI.rejectWithValue(message);
        }
    }
});

export const LogOut = createAsyncThunk("user/LogOut", async() => {
    await axios.delete('http://localhost:5001/logout');
});

export const authSlice = createSlice({
    name: "auth",
    initialState,
    reducers:{
        reset: (state) => initialState
    },
    extraReducers:(builder) =>{
        builder.addCase(LoginUser.pending, (state) =>{
            state.isLoading = true;
        });
        builder.addCase(LoginUser.fulfilled, (state, action) =>{
            state.isLoading = false;
            state.isSuccess = true;
            state.user = action.payload;
        });
        builder.addCase(LoginUser.rejected, (state, action) =>{
            state.isLoading = false;
            state.isError = true;
            state.message = action.payload;
        })

        // Get User Login
        builder.addCase(getMe.pending, (state) =>{
            state.isLoading = true;
        });
        builder.addCase(getMe.fulfilled, (state, action) =>{
            state.isLoading = false;
            state.isSuccess = true;
            state.user = action.payload;
        });
        builder.addCase(getMe.rejected, (state, action) =>{
            state.isLoading = false;
            state.isError = true;
            state.message = action.payload;
        })
    }
});

export const {reset} = authSlice.actions;
export default authSlice.reducer;

仪表板页

代码语言:javascript
复制
const Dashboard = () => {

  const dispatch = useDispatch();
  const navigate = useNavigate();
  const { isError } = useSelector((state) => state.auth);

  useEffect(() => {
    dispatch(getMe());
  }, [dispatch]);

  useEffect(() => {
    if (isError) {
      navigate("/");
    }
  }, [isError, navigate]);
  return (
    <Layout>
      <Welcome />
    </Layout>
  );
};

export default Dashboard;
EN

回答 1

Stack Overflow用户

发布于 2022-10-03 16:03:59

从登录组件中删除useEffect并更新Auth函数,如

代码语言:javascript
复制
const Auth = (e) => {
    e.preventDefault();
    dispatch(LoginUser({ email, password }))
    .unwrap() // <-- async Thunk returns a promise, that can be 'unwrapped')
    .then(() => navigate("/dashboard"))
  };

解释:在使用createAsyncThunk API时,返回的函数在默认情况下是预先化的。您可以使用using ()方法等待承诺解析(我猜是由Rust (我猜是…)完成的)。当承诺被解决后,它可以被更多的连接起来,然后()调用,这样您就可以从那里导航。

Refference:useNavigate blocks rest of the content in createAsyncThunk, redux toolkit

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73936916

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档