reactjs - 一旦我提交表单并从输入字段中获取值并将其分配给 api url 并获得响应,我想使用 useEffect
问题描述
我正在尝试使用 API 制作 ip 跟踪器。我正在使用表单输入和 useState 从用户那里获取一个值并将其分配给 API ip 值。我正在使用自定义 useFetch 挂钩来使用来自的值获取数据state.我希望 useFetch 仅在提交表单或单击提交按钮时运行。但它最初呈现 null 并在我每次输入时呈现。我是新来的反应和从头开始学习。请指出我的错误。
这是我的 useFetch 钩子:
import { useState, useEffect } from 'react';
export const useFetch = (url, options, dep) => {
const [response, setResponse] = useState(null);
const [error, setError] = useState(null);
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
const fetchData = async () => {
setIsLoading(true);
try {
const res = await fetch(url, options);
const json = await res.json();
setResponse(json);
setIsLoading(false);
} catch (error) {
setError(error);
}
};
fetchData();
}, [dep]);
return { response, error, isLoading };
};
头文件:
import { useState } from 'react';
import { FaArrowRight } from 'react-icons/fa';
import React from 'react';
import { Form, FormInput, Head, HeadLine, Button } from './Header.elements';
import { useFetch } from '../../useFetch';
const Header = () => {
const [value, setValue] = useState('');
const [Ip, setIp] = useState(value);
const API_KEY = 'at_xtpIidIz9vUqEzBODaUwtVRXf';
const URL = `https://geo.ipify.org/api/v1?apiKey=${API_KEY}&ipAddress=${Ip}`;
const handleSubmit = (e) => {
e.preventDefault();
setIp(value);
};
const { isLoading, response, dep } = useFetch(URL, '', setIp);
console.log(response);
const handleChange = (e) => {
setValue(e.target.value);
};
return (
<>
{/* styled components */}
<Head>
<HeadLine>IP Address Tracker</HeadLine>
<Form onSubmit={handleSubmit}>
<FormInput
onChange={handleChange}
value={value}
placeholder='Search for any IP address or Domain'
/>
<Button type='submit'>
<FaArrowRight />
</Button>
</Form>
</Head>
</>
);
};
export default Header;
App.js 文件:
import Header from './components/Header/Header';
import GlobalStyle from './globalStyles';
function App() {
return (
<>
<GlobalStyle />
<Header />
</>
);
}
export default App;
解决方案
React 钩子应该在每次组件渲染时运行,它在钩子规则中有所描述。您可能看到的是每次渲染的返回值。我敢肯定,如果您在浏览器中检查了您的网络选项卡,您只会看到 1 个来自useEffect
的回调函数发出的请求fetch
。
我认为你已经混淆了useFetch
依赖关系,因为setIp
它是状态更新函数并且是一个稳定的引用,所以它永远不会触发useEffect
钩子来重新运行回调。我认为您希望Ip
状态值成为依赖项,即useFetch(URL, '', Ip);
.
const { isLoading, response, error } = useFetch(URL, '', Ip);
钩子:您可能还想清除finally
块中的加载状态,因此无论成功或失败,您都可以在不再主动获取数据时相应地更新您的 UI。我建议还传递多个依赖项,以防您有更多依赖项。这里的变化是只传递一个完整的依赖数组。
export const useFetch = (url, options, deps) => {
const [response, setResponse] = useState(null);
const [error, setError] = useState(null);
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
const fetchData = async () => {
setIsLoading(true);
try {
const res = await fetch(url, options);
const json = await res.json();
setResponse(json);
} catch (error) {
setError(error);
} finally {
setIsLoading(false);
}
};
fetchData();
}, deps); // <-- pass dependencies
return { response, error, isLoading };
};
用法:这里定义了依赖数组
const { isLoading, response, error } = useFetch(URL, '', [Ip]);
推荐阅读
- mongodb - 如何在 Kubernetes 集群上使用 mongo-express 或 RockMongo 等 MongoDB GUI 工具
- javascript - 创建 React App 中的工作箱而不弹出
- tensorflow - 学习模型的许可证是什么?
- docker - 如何将 rabbitmq_delayed_message_exchange 插件添加到运行 docker 的 RabbitMQ
- wordpress - 如何从 get_categories 对象中获取 id
- ios - MagicalRecord - 如何处理不推荐使用的方法?
- node.js - Sequelize:如何在 3 个表之间建立关系
- android - Android SyncAdapter 导致 InterruptedException
- alexa - ask-cli api 或 lambda 不存在
- fullcalendar - 使用Javascript从外部修改约会事件