![](/img/trans.png)
[英]React Hook "useAxios" is called in function "onFinish" that is neither a React function component nor a custom React Hook function
[英]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
稍作更改,因为钩子只能在组件的主体中调用,而不是有条件地调用。 我在该钩子中添加了一个参数来处理自动获取。 在这种情况下,您不希望它自动触发 fetch,而是强制触发,因此只需从钩子中返回 fetcher 函数并强制使用它。 顺便说一句,最好不要耦合钩子并创建两个单独的钩子,比如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 };
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.