[英]Calling a React Hook in a Context
我正在使用https://github.com/flatlogic/react-material-admin ,它是一个基于Material UI
的React Admin Console
,并带有 react context
和hooks
设计。
该项目为 User UserContext.js
定义了一个 Context ,代码很简单( https://raw.githubusercontent.com/flatlogic/react-material-admin/master/src/context/UserContext.js ):
import React from "react";
var UserStateContext = React.createContext();
var UserDispatchContext = React.createContext();
function userReducer(state, action) {
switch (action.type) {
case "LOGIN_SUCCESS":
return { ...state, isAuthenticated: true };
case "SIGN_OUT_SUCCESS":
return { ...state, isAuthenticated: false };
default: {
throw new Error(`Unhandled action type: ${action.type}`);
}
}
}
function UserProvider({ children }) {
var [state, dispatch] = React.useReducer(userReducer, {
isAuthenticated: !!localStorage.getItem("id_token"),
});
return (
<UserStateContext.Provider value={state}>
<UserDispatchContext.Provider value={dispatch}>
{children}
</UserDispatchContext.Provider>
</UserStateContext.Provider>
);
}
function useUserState() {
var context = React.useContext(UserStateContext);
if (context === undefined) {
throw new Error("useUserState must be used within a UserProvider");
}
return context;
}
function useUserDispatch() {
var context = React.useContext(UserDispatchContext);
if (context === undefined) {
throw new Error("useUserDispatch must be used within a UserProvider");
}
return context;
}
export { UserProvider, useUserState, useUserDispatch, loginUser, signOut };
// ###########################################################
function loginUser(dispatch, login, password, history, setIsLoading, setError) {
setError(false);
setIsLoading(true);
if (!!login && !!password) {
setTimeout(() => {
localStorage.setItem('id_token', 1)
setError(null)
setIsLoading(false)
dispatch({ type: 'LOGIN_SUCCESS' })
history.push('/app/dashboard')
}, 2000);
} else {
dispatch({ type: "LOGIN_FAILURE" });
setError(true);
setIsLoading(false);
}
}
function signOut(dispatch, history) {
localStorage.removeItem("id_token");
dispatch({ type: "SIGN_OUT_SUCCESS" });
history.push("/login");
}
正如您所看到的loginUser
代码是虚拟的,并且没有调用任何 API。 我尝试使用带有钩子的 api fetch 将其连接到服务器。 我使用了swr
( https://github.com/zeit/swr ),这看起来很简单
`....useSWR('/api/login'); ...`
我得到了错误:
React Hook "useSWR" is called in function "loginUser" which is neither a React
function component or a custom React Hook function react-hooks/rules-of-hooks
看来我不能把提取放在这里。 但从逻辑上讲,它是它应该出现的地方!
我如何使用swr
或这里?!
你需要做这样的事情:
function FetchOnClick() {
const [shouldFetch, setShouldFetch] = React.useState(false);
const { data } = useSWR(!shouldFetch ? null : "/api/users/1", fetcher);
return (
<>
<button disable={shouldFetch} onClick={ () => setShouldFetch(true) }>Fetch</button>
{data ? <h1>{data.fullName}</h1> : null}
</>
);
}
受到@sergiodxa 代码的启发: https : //github.com/vercel/swr/issues/254
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.