I want to use useEffect once i submit a form and take the value from input field and assign it to a api url and get response

I am trying to make a ip tracker with an API.I am using form input and useState to get a value from the user and assign it to the API ip value.I am using a custom useFetch hook to fetch the data using the value from state.I want the useFetch to run only when form is submitted or submit button is clicked.But it renders null initially and renders every time i put a input. I am new to react and learning from scratch.please point out my mistakes.

Here is my useFetch hook:

  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 };
    };

Header file:

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 file:

import Header from './components/Header/Header';
import GlobalStyle from './globalStyles';

function App() {
    return (
        <>
            <GlobalStyle />
            <Header />
        </>
    );
}

export default App;

I’m a little confused.

Your hook returns this:

return { response, error, isLoading };

But you are destructuring of the return from it:

const { isLoading, response, dep } // ...

Where is that dep property coming from? Won’t it always be undefined here?

Furthermore, your hook takes in these params:

export const useFetch = (url, options, dep) => {

but you call it with this:

useFetch(URL, '', setIp)

So, the setter from your state hook is your dependency? I would not expect that to change, except perhaps at load time.

Also, if you are going to pass the dependencies to your useFetch hook, I’d want to pass them as an array, in case I had more than one, to make it more flexible in the future.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.