首页 > 解决方案 > 状态未显示在 Redux 商店中

问题描述

我是 Redux 的新手,对我来说是裸露的。

我正在开发一个基本的新闻应用程序,前端使用 TypeScript 和 React,后端使用 Node.js 和 Express。我最近开始将 Redux 集成到我的应用程序中。

当用户登录我的应用程序时,我目前正在将他们重定向到他们的个人资料页面(组件)。配置文件组件有一个 useEffect,然后它将调用我的后端 API(使用 Thunk)来获取用户并将其放入 Redux 存储中,如果它还不能在那里找到它。API 返回用户对象(我可以在我的终端中验证 API 正在返回用户对象),但用户永远不会出现在商店中,因此我无法呈现他们的任何信息。我将附上所有相关代码,希望有人能发现问题。

authReucer.ts:

import { User } from "../../../../shared/User";
import {
  AuthDispatchTypes,
  USER_SUCCESS,
  USER_FAIL,
  USER_LOADING,
} from "../actions/authActionsTypes";

interface UserRes {
  user: User;
  status: number;
  authenticated: boolean;
}

export interface AuthState {
  loading: boolean;
  user?: UserRes;
  authenticated: boolean;
}

const defaultState: AuthState = {
  loading: false,
  authenticated: false,
};

const authReducer = (
  state: AuthState = defaultState,
  action: AuthDispatchTypes
): AuthState => {
  switch (action.type) {
    case USER_FAIL:
      return {
        loading: false,
        authenticated: false,
      };
    case USER_LOADING:
      return {
        loading: true,
        authenticated: false,
      };
    case USER_SUCCESS:
      return {
        loading: false,
        authenticated: true,
        user: action.payload,
      };
    default:
      return state;
  }
};

export default authReducer;

authActionTypes.ts:

import { User } from "../../../../shared/User";

export const USER_LOADING = "USER_LOADING";
export const USER_FAIL = "USER_FAIL";
export const USER_SUCCESS = "USER_SUCCESS";

interface UserLoading {
  type: typeof USER_LOADING;
}

interface UserFail {
  type: typeof USER_FAIL;
}

interface UserSuccess {
  type: typeof USER_SUCCESS;
  payload: {
    user: User;
    status: number;
    authenticated: boolean;
  };
}

export type AuthDispatchTypes = UserLoading | UserFail | UserSuccess;

authActions.ts:

import axios from "axios";
import { Dispatch } from "redux";
import {
  AuthDispatchTypes,
  USER_LOADING,
  USER_FAIL,
  USER_SUCCESS,
} from "./authActionsTypes";

export const setUser = () => async (dispatch: Dispatch<AuthDispatchTypes>) => {
  try {
    dispatch({
      type: USER_LOADING,
    });

    const res = await axios.get("auth/login/success");

    dispatch({
      type: USER_SUCCESS,
      payload: res.data,
    });
  } catch (error) {
    dispatch({
      type: USER_FAIL,
    });
  }
};

个人资料.tsx:

import React, { useEffect, useState } from "react";
import { Navbar } from "../components/Navbar";
import { setUser } from "../store/actions/authActions";
import { useSelector, useDispatch } from "react-redux";
import { AuthState } from "../store/reducers/authReducer";

export const Profile = () => {
  const dispatch = useDispatch();
  const userState = useSelector<AuthState, AuthState["user"]>(
    (state) => state.user
  );
const authenticated = useSelector<AuthState, AuthState["authenticated"]>(
    (state) => state.authenticated
  );

useEffect(() => {
    // Check if there's a user authenticated but we dont yet have it
    if (userState === undefined && authenticated) {
      dispatch(setUser);
    }
  });

return (
    <div>
      <Navbar
      //authenticated={authenticated}
      //handleNotAuthenticated={handleNotAuthenticated}
      />
      <h1>Profile</h1>
      <h2>{userState && userState.user.username}</h2>
      <h2>{userState && userState.user.email}</h2>
      <img src={userState && userState.user.photo} alt={"profile"} />
      <h2>Your News Sources</h2>
      { <ul>
        {user &&
          user.sources.map((source: any) => {
            return <li key={source.url}>{source.name}</li>;
          })}
      </ul> }
    </div>
  );
};

索引.ts:

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { createStore, Store, applyMiddleware } from "redux";
import { Provider } from "react-redux";
import rootReducer from "./store/reducers/rootReducer";
import thunk from "redux-thunk";
import { composeWithDevTools } from "redux-devtools-extension";

const store: Store = createStore(
  rootReducer,
  composeWithDevTools(applyMiddleware(thunk))
);

export type RootStore = ReturnType<typeof rootReducer>;

ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>,
  document.getElementById("root")
);

reportWebVitals();

标签: reactjstypescriptreduxreact-reduxredux-thunk

解决方案


推荐阅读