在既不是 React 函数组件也不是自定义 React Hook 函数的函数中调用了 React Hook "useAxios"
React Hook "useAxios" is called in function that is neither a React function component nor a custom React Hook function
我创建了一个自定义 useAxios
挂钩来进行 api 调用。
我正尝试在我的登录组件中使用它,如下所示。
import { useContext, useState } from 'react';
import './login.scss';
import { useNavigate } from 'react-router-dom';
import { useAxios } from '../../api/use-axios';
import ApiConfig from '../../api/api-config';
import { AuthContext } from '../../context/AuthContext';
const LOGIN_AXIOS_CONFIG = ApiConfig.AUTH.LOGIN;
const Login = () => {
const [loginError, setLoginError] = useState('');
const [phone, setPhone] = useState('');
const [password, setPassword] = useState('');
const navigate = useNavigate();
const { dispatch } = useContext(AuthContext);
const handleLogin = (e) => {
e.preventDefault();
LOGIN_AXIOS_CONFIG.data = {
phone,
password,
};
const { response: loginData, error } = useAxios(LOGIN_AXIOS_CONFIG);
if (error) {
setLoginError(error);
}
if (loginData) {
dispatch({ type: 'LOGIN', payload: loginData });
navigate('/');
}
};
return (
<div className="login">
<div className="logo">
<h1>LOGO</h1>
<h3>LOGO DESCRIPTION</h3>
</div>
<form onSubmit={handleLogin}>
<input type="number" placeholder="phone" onChange={(e) => setPhone(e.target.value)} />
<input type="password" placeholder="password" onChange={(e) => setPassword(e.target.value)} />
<button type="submit">Submit</button>
{loginError && <span>{loginError}</span>}
</form>
</div>
);
};
export default Login;
使用-axios.js
import { useState, useEffect } from 'react';
import axios from 'axios';
export const useAxios = (axiosParams) => {
const [response, setResponse] = useState(undefined);
const [error, setError] = useState('');
const [loading, setLoading] = useState(true);
const fetchData = async (params) => {
try {
const result = await axios.request({
...params,
method: params.method || 'GET',
headers: {
accept: 'application/json',
authorization:
'Bearer my-token',
},
});
console.log(result.data);
setResponse(result.data);
} catch (error) {
setError(error);
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchData(axiosParams);
}, [axiosParams]); // execute once only
return { response, error, loading };
};
反应是否看到 use
前缀并给出错误?
我该如何解决这个问题?
您需要对自定义挂钩稍作更改 useAxios
,因为挂钩只能在组件主体中调用,不能有条件地调用。我向该挂钩添加了一个参数来处理 auto-fetch。在这种情况下,您不希望它自动触发提取,而是命令式的,所以只需 return 钩子中的提取器函数并命令式地使用它。顺便说一句,最好不要耦合钩子并创建两个单独的钩子,例如 useAxiosOnMount
、useAxiosOnAction
。为简单起见,我将在此处编辑您的 useAxios
挂钩:
const Login = () => {
const [loginError, setLoginError] = useState('');
const [phone, setPhone] = useState('');
const [password, setPassword] = useState('');
const navigate = useNavigate();
const { dispatch } = useContext(AuthContext);
const {fetch, loading, response, error} = useAxios(LOGIN_AXIOS_CONFIG, false)
useEffect(() => {
if (response) // do something
if (error) // do something else
},[response,error])
const handleLogin = (e) => {
e.preventDefault();
fetch()
};
return (
<div className="login">
<div className="logo">
<h1>LOGO</h1>
<h3>LOGO DESCRIPTION</h3>
</div>
<form onSubmit={handleLogin}>
<input type="number" placeholder="phone" onChange={(e) => setPhone(e.target.value)} />
<input type="password" placeholder="password" onChange={(e) => setPassword(e.target.value)} />
<button type="submit">Submit</button>
{loginError && <span>{loginError}</span>}
</form>
</div>
);
};
export default Login;
use-axios.js
export const useAxios = (axiosParams, isAuto) => {
const [response, setResponse] = useState(undefined);
const [error, setError] = useState('');
const [loading, setLoading] = useState(true);
const fetchData = async (params) => {
try {
const result = await axios.request({
...params,
method: params.method || 'GET',
headers: {
accept: 'application/json',
authorization:
'Bearer my-token',
},
});
console.log(result.data);
setResponse(result.data);
} catch (error) {
setError(error);
} finally {
setLoading(false);
}
};
useEffect(() => {
if (isAuto)
fetchData(axiosParams);
}, [axiosParams, isAuto]); // execute once only
return { fetch: () => fetchData(axiosParams), response, error, loading };
};
我创建了一个自定义 useAxios
挂钩来进行 api 调用。
我正尝试在我的登录组件中使用它,如下所示。
import { useContext, useState } from 'react';
import './login.scss';
import { useNavigate } from 'react-router-dom';
import { useAxios } from '../../api/use-axios';
import ApiConfig from '../../api/api-config';
import { AuthContext } from '../../context/AuthContext';
const LOGIN_AXIOS_CONFIG = ApiConfig.AUTH.LOGIN;
const Login = () => {
const [loginError, setLoginError] = useState('');
const [phone, setPhone] = useState('');
const [password, setPassword] = useState('');
const navigate = useNavigate();
const { dispatch } = useContext(AuthContext);
const handleLogin = (e) => {
e.preventDefault();
LOGIN_AXIOS_CONFIG.data = {
phone,
password,
};
const { response: loginData, error } = useAxios(LOGIN_AXIOS_CONFIG);
if (error) {
setLoginError(error);
}
if (loginData) {
dispatch({ type: 'LOGIN', payload: loginData });
navigate('/');
}
};
return (
<div className="login">
<div className="logo">
<h1>LOGO</h1>
<h3>LOGO DESCRIPTION</h3>
</div>
<form onSubmit={handleLogin}>
<input type="number" placeholder="phone" onChange={(e) => setPhone(e.target.value)} />
<input type="password" placeholder="password" onChange={(e) => setPassword(e.target.value)} />
<button type="submit">Submit</button>
{loginError && <span>{loginError}</span>}
</form>
</div>
);
};
export default Login;
使用-axios.js
import { useState, useEffect } from 'react';
import axios from 'axios';
export const useAxios = (axiosParams) => {
const [response, setResponse] = useState(undefined);
const [error, setError] = useState('');
const [loading, setLoading] = useState(true);
const fetchData = async (params) => {
try {
const result = await axios.request({
...params,
method: params.method || 'GET',
headers: {
accept: 'application/json',
authorization:
'Bearer my-token',
},
});
console.log(result.data);
setResponse(result.data);
} catch (error) {
setError(error);
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchData(axiosParams);
}, [axiosParams]); // execute once only
return { response, error, loading };
};
反应是否看到 use
前缀并给出错误?
我该如何解决这个问题?
您需要对自定义挂钩稍作更改 useAxios
,因为挂钩只能在组件主体中调用,不能有条件地调用。我向该挂钩添加了一个参数来处理 auto-fetch。在这种情况下,您不希望它自动触发提取,而是命令式的,所以只需 return 钩子中的提取器函数并命令式地使用它。顺便说一句,最好不要耦合钩子并创建两个单独的钩子,例如 useAxiosOnMount
、useAxiosOnAction
。为简单起见,我将在此处编辑您的 useAxios
挂钩:
const Login = () => {
const [loginError, setLoginError] = useState('');
const [phone, setPhone] = useState('');
const [password, setPassword] = useState('');
const navigate = useNavigate();
const { dispatch } = useContext(AuthContext);
const {fetch, loading, response, error} = useAxios(LOGIN_AXIOS_CONFIG, false)
useEffect(() => {
if (response) // do something
if (error) // do something else
},[response,error])
const handleLogin = (e) => {
e.preventDefault();
fetch()
};
return (
<div className="login">
<div className="logo">
<h1>LOGO</h1>
<h3>LOGO DESCRIPTION</h3>
</div>
<form onSubmit={handleLogin}>
<input type="number" placeholder="phone" onChange={(e) => setPhone(e.target.value)} />
<input type="password" placeholder="password" onChange={(e) => setPassword(e.target.value)} />
<button type="submit">Submit</button>
{loginError && <span>{loginError}</span>}
</form>
</div>
);
};
export default Login;
use-axios.js
export const useAxios = (axiosParams, isAuto) => {
const [response, setResponse] = useState(undefined);
const [error, setError] = useState('');
const [loading, setLoading] = useState(true);
const fetchData = async (params) => {
try {
const result = await axios.request({
...params,
method: params.method || 'GET',
headers: {
accept: 'application/json',
authorization:
'Bearer my-token',
},
});
console.log(result.data);
setResponse(result.data);
} catch (error) {
setError(error);
} finally {
setLoading(false);
}
};
useEffect(() => {
if (isAuto)
fetchData(axiosParams);
}, [axiosParams, isAuto]); // execute once only
return { fetch: () => fetchData(axiosParams), response, error, loading };
};