如何通过Dispatch Payload将Struct传递给ReactReducer

问题描述 投票:0回答:1

React 相对较新。我正在尝试为网络应用程序构建登录功能。 (在 React 中)我想要求用户在访问内部页面和功能之前先登录。 (因为用户数据将链接到他们所做的、所看到的等等......)

我想将“用户”设置为全局结构/对象,我可以引用各种功能 - 并在登录时传递“用户数据” - (我现在手动设置用于测试的结构 - 但最终将从登录 api) 到调度,这应该使用所有相关信息更新“用户状态”。当我这样做时 - 我收到以下错误:

Objects are not valid as a React child (found: object with keys {esid, uuid, status...

错误发生在 AuthProvider 中。(最后列出的代码)为了完整起见,这里是到达那里的代码,因为我怀疑它可能会影响此错误(?):

在 App.js 中,我在页面周围有一个包装器......在需要登录的页面周围有一个包装器。

注意:为了进行测试,我使用“FakeUser”。当我集成用于登录凭据验证的 API 时,它将被替换。

完整代码: 应用程序.js

export default function App() {
  return (
<div className="App">
  <AuthProvider>
    <LocationsProvider>
      <StoriesProvider>
        <BrowserRouter>
          <Routes>
            <Route index element={<Login />} />

            <Route
              path="/"
              element={
                <ProtectedRoute>
                  <Route path="home" element={<Homepage />} />
                  <Route path="locations" element={<Locations />} />
                  <Route path="locations/:id" element={<LocationEdit />} />
                  <Route path="locationnew" element={<LocationNew />} />
                  <Route path="memories" element={<Memories />} />
                  <Route path="connections" element={<Connections />} />
                  <Route path="story" element={<Story />} />
                </ProtectedRoute>
              }
            ></Route>

            <Route path="*" element={<PageNotFound />} />
          </Routes>
        </BrowserRouter>
      </StoriesProvider>
    </LocationsProvider>
  </AuthProvider>
</div>

受保护路线

import { useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { useAuth } from "../contexts/AuthContext";

function ProtectedRoute({ children }) {
  const { isAuthenticated } = useAuth();
  const navigate = useNavigate();

  useEffect(
    function () {
      if (!isAuthenticated) navigate("/");
    },
    [isAuthenticated, navigate]
  );

  return isAuthenticated ? children : null;
}

export default ProtectedRoute;

登录码

export default function Login() {
  // PRE-FILL FOR DEV PURPOSES
  const [email, setEmail] = useState("[email protected]");
  const [password, setPassword] = useState("myfakepassword");
  const { login, isAuthenticated } = useAuth();
  const navigate = useNavigate();

  function handleSubmit(e) {
    e.preventDefault();
    console.log("Logging in...");
    if (email && password) login(email, password);
  }

  useEffect(
    function () {
      if (isAuthenticated) navigate("/home", { replace: true });
    },
    [isAuthenticated]
  );

  return (
    <main className={styles.login}>
      <form className={styles.form} onSubmit={handleSubmit}>
        <div className={styles.row}>
          <label htmlFor="email">Email address</label>
          <input
            type="email"
            id="email"
            onChange={(e) => setEmail(e.target.value)}
            value={email}
          />
        </div>

        <div className={styles.row}>
          <label htmlFor="password">Password</label>
          <input
            type="password"
            id="password"
            onChange={(e) => setPassword(e.target.value)}
            value={password}
          />
        </div>

        <div>
          <Button type="primary">Login</Button>
        </div>
      </form>
    </main>
  );
}

验证提供者:

import { createContext, useContext, useReducer } from "react";
const AuthContext = createContext();

const initialState = {
  user: null,
  isAuthenticated: false,
};

function reducer(state, action) {
  switch (action.type) {
    case "login":
      return { ...state, user: action.payload, isAuthenticated: true };
    case "logout":
      return { ...state, user: null, isAuthenticated: false };
    default:
      throw new Error("Unknown action");
  }
}

const FAKE_USER = {
  esid: "1",
  uuid: "11111111-0000-2222-3333333333333333",
  status: "1",
  firstName: "Test",
  lastName: "User",
  screenname: "TestUser01",
  profilepic: "avatar.jpg",
  email: "[email protected]",
};

function AuthProvider({ children }) {
  const [{ user, isAuthenticated }, dispatch] = useReducer(
    reducer,
    initialState
  );

  function login(email, password) {
    console.log(FAKE_USER);
    //API Connectivity and verification will go here...
    //payload is causing ERROR

    if (email === "[email protected]" && password === "myfakepassword")
      dispatch({ type: "login", payload: FAKE_USER });
  }

  function logout() {
    dispatch({ type: "logout" });
  }

  return (
    <AuthContext.Provider value={{ user, isAuthenticated, login, logout }}>
      {children}
    </AuthContext.Provider>
  );
}

function useAuth() {
  const context = useContext(AuthContext);
  if (context === undefined)
    throw new Error("AuthContext was used outside AuthProvider");
  return context;
}

export { AuthProvider, useAuth };
reactjs react-hooks dispatch
1个回答
0
投票

答案是 - - 该代码有效。导致错误的用户数据正在不同的页面上输出

<div>{user}</div>

但是,这个组件被埋没了,错误并没有在错误中列出这个页面名称。

它需要是:

<div>{user.firstname}</div>

调整该代码修复了它。 对其他人请注意:有时您必须深入挖掘嵌套文件......(生我自己的气)

© www.soinside.com 2019 - 2024. All rights reserved.