Uncaught (in promise) TypeError: dispatch is not a function useContext/useReducer
Uncaught (in promise) TypeError: dispatch is not a function useContext/useReducer
我是新手。我在一个博客网站上工作,我需要在其中创建一个登录页面。我面临以下错误:
TypeError: dispatch 不是函数
以下是我处理提交和请求 API 的代码。我正进入(状态
...
const { dispatch, isFetching } = useContext(Context);
const handleSubmit = async (e) => {
e.preventDefault();
dispatch({ type: "LOGIN_START" });
try {
const res = await axios.post("http://localhost:5001/api/auth/login", {
username: userRef.current.value,
password: passwordRef.current.value,
});
dispatch({ type: "LOGIN_SUCCESS", payload: res.data });
} catch (err) {
dispatch({ type: "LOGIN_FAILURE" });
}
};
...
以下是我的表单代码:
...
return (
<div className="login">
<span className="loginTitle">Login</span>
<form className="loginForm" onSubmit={(e) => handleSubmit(e)}>
<label>Username</label>
<input
type="text"
className="loginInput"
placeholder="Enter your username..."
ref={userRef}
/>
<label>Password</label>
<input
type="password"
className="loginInput"
placeholder="Enter your password..."
ref={passwordRef}
/>
<button className="loginButton" type="submit" disabled={isFetching}>
Login
</button>
</form>
<button className="loginRegisterButton">
<Link className="link" to="/register">
Register
</Link>
</button>
</div>
);
...
以下是上下文提供程序
...
import { createContext, useEffect, useReducer } from "react";
import Reducer from "./Reducer";
const INITIAL_STATE = {
user: JSON.parse(localStorage.getItem("user")) || null,
isFetching: false,
error: false,
};
export const Context = createContext(INITIAL_STATE);
export const ContextProvider = ({ children }) => {
const [state, dispatch] = useReducer(Reducer, INITIAL_STATE);
useEffect(() => {
localStorage.setItem("user", JSON.stringify(state.user));
}, [state.user]);
return (
<Context.Provider
value={{
user: state.user,
isFetching: state.isFetching,
error: state.error,
dispatch,
}}
>
{children}
</Context.Provider>
);
};
...
以下是我的 app.js,其中包含所有根节点
...
import Home from "./Pages/home/Home";
import TopBar from "./components/topbar/TopBar";
import Single from "./Pages/single/Single";
import Write from "./Pages/write/Write";
import Settings from "./Pages/settings/Settings";
import Login from "./Pages/login/Login";
import Register from "./Pages/register/Register";
import { useContext } from "react";
import { Context } from "./context/Context";
import {
BrowserRouter as Router,
Routes,
Route,
Link,
BrowserRouter
} from "react-router-dom"
function App() {
const { user } = useContext(Context);
return (
<BrowserRouter >
<TopBar />
<Routes>
<Route exact path="/" element={<Home />} />
<Route path="register" element={user ? <Home /> : <Register />} />
<Route path="login" element={ user ? <Home /> : <Login />} />
<Route path="write" element={user ? <Write /> : <Register />} />
<Route path="settings" element={user ? <Settings /> : <Register />} />
<Route path="post/:postId" element={<Single />} />
</Routes>
</BrowserRouter >
);
}
export default App;
...
有人可以帮我解决这个问题吗?
您显然是从上下文中获取默认值,而您的默认值没有 dispatch
函数。要使上下文正常工作,组件树上必须有一个上下文提供程序高于尝试使用上下文的组件。
您要么根本没有渲染 ContextProvider,要么在组件树的错误部分渲染它。
例如,以下将起作用:
const App = () => {
return (
<ContextProvider>
<MyForm />
<ContextProvider>
)
}
const MyForm = () => {
const { dispatch, isFetching } = useContext(Context);
const handleSubmit = async (e) => {
// ...
}
return (
<div className="login">
// ...
</div>
)
}
但这不会(提供者是消费者的child):
const MyForm = () => {
const { dispatch, isFetching } = useContext(Context);
const handleSubmit = async (e) => {
// ...
}
return (
<ContextProvider>
<div className="login">
// ...
</div>
</ContextProvider>
)
}
这也不会(提供者存在,但不是 MyForm 的祖先)
const App = () => {
return (
<div>
<MyForm />
<ContextProvider />
</div>
)
}
我是新手。我在一个博客网站上工作,我需要在其中创建一个登录页面。我面临以下错误: TypeError: dispatch 不是函数
以下是我处理提交和请求 API 的代码。我正进入(状态 ...
const { dispatch, isFetching } = useContext(Context);
const handleSubmit = async (e) => {
e.preventDefault();
dispatch({ type: "LOGIN_START" });
try {
const res = await axios.post("http://localhost:5001/api/auth/login", {
username: userRef.current.value,
password: passwordRef.current.value,
});
dispatch({ type: "LOGIN_SUCCESS", payload: res.data });
} catch (err) {
dispatch({ type: "LOGIN_FAILURE" });
}
};
...
以下是我的表单代码:
...
return (
<div className="login">
<span className="loginTitle">Login</span>
<form className="loginForm" onSubmit={(e) => handleSubmit(e)}>
<label>Username</label>
<input
type="text"
className="loginInput"
placeholder="Enter your username..."
ref={userRef}
/>
<label>Password</label>
<input
type="password"
className="loginInput"
placeholder="Enter your password..."
ref={passwordRef}
/>
<button className="loginButton" type="submit" disabled={isFetching}>
Login
</button>
</form>
<button className="loginRegisterButton">
<Link className="link" to="/register">
Register
</Link>
</button>
</div>
);
...
以下是上下文提供程序
...
import { createContext, useEffect, useReducer } from "react";
import Reducer from "./Reducer";
const INITIAL_STATE = {
user: JSON.parse(localStorage.getItem("user")) || null,
isFetching: false,
error: false,
};
export const Context = createContext(INITIAL_STATE);
export const ContextProvider = ({ children }) => {
const [state, dispatch] = useReducer(Reducer, INITIAL_STATE);
useEffect(() => {
localStorage.setItem("user", JSON.stringify(state.user));
}, [state.user]);
return (
<Context.Provider
value={{
user: state.user,
isFetching: state.isFetching,
error: state.error,
dispatch,
}}
>
{children}
</Context.Provider>
);
};
...
以下是我的 app.js,其中包含所有根节点 ...
import Home from "./Pages/home/Home";
import TopBar from "./components/topbar/TopBar";
import Single from "./Pages/single/Single";
import Write from "./Pages/write/Write";
import Settings from "./Pages/settings/Settings";
import Login from "./Pages/login/Login";
import Register from "./Pages/register/Register";
import { useContext } from "react";
import { Context } from "./context/Context";
import {
BrowserRouter as Router,
Routes,
Route,
Link,
BrowserRouter
} from "react-router-dom"
function App() {
const { user } = useContext(Context);
return (
<BrowserRouter >
<TopBar />
<Routes>
<Route exact path="/" element={<Home />} />
<Route path="register" element={user ? <Home /> : <Register />} />
<Route path="login" element={ user ? <Home /> : <Login />} />
<Route path="write" element={user ? <Write /> : <Register />} />
<Route path="settings" element={user ? <Settings /> : <Register />} />
<Route path="post/:postId" element={<Single />} />
</Routes>
</BrowserRouter >
);
}
export default App;
...
有人可以帮我解决这个问题吗?
您显然是从上下文中获取默认值,而您的默认值没有 dispatch
函数。要使上下文正常工作,组件树上必须有一个上下文提供程序高于尝试使用上下文的组件。
您要么根本没有渲染 ContextProvider,要么在组件树的错误部分渲染它。
例如,以下将起作用:
const App = () => {
return (
<ContextProvider>
<MyForm />
<ContextProvider>
)
}
const MyForm = () => {
const { dispatch, isFetching } = useContext(Context);
const handleSubmit = async (e) => {
// ...
}
return (
<div className="login">
// ...
</div>
)
}
但这不会(提供者是消费者的child):
const MyForm = () => {
const { dispatch, isFetching } = useContext(Context);
const handleSubmit = async (e) => {
// ...
}
return (
<ContextProvider>
<div className="login">
// ...
</div>
</ContextProvider>
)
}
这也不会(提供者存在,但不是 MyForm 的祖先)
const App = () => {
return (
<div>
<MyForm />
<ContextProvider />
</div>
)
}