Проблема повторного вызова перехвата реакции "useEffect" - PullRequest
0 голосов
/ 08 мая 2020

Я работаю над новым небольшим проектом в React и использую перехватчики React. Конечная цель этого приложения - получить данные о погоде в определенном городе из API openweather и отобразить их на экране. Я создал настраиваемую ловушку для извлечения данных из конечной точки и передал три аргумента, как показано ниже:

export const useHttp = (baseURL, dependancies, isSubmit) => {

    // Inizialize isLoading to false 
    const [isLoading, setLoading] = useState(false);

    // Initialize the fetched data to an empty string
    const [fetchedData, setFetchedData] = useState('');

    useEffect(() => {
        /*Check if isSubmit is true before fetching the corresponding 
        data*/
        if (isSubmit) {

            // set isLoading to true until we get the data
            setLoading(true);

            // Start fetching the data from the url received
            fetch(baseURL)
                .then(response => {
                    if (!response.ok) {
                        throw new Error('Failed to fetch. ');
                    }
                    return response.json();
                })
                // Return the data when fetched successfully
                .then(data => {
                    setLoading(false);
                    setFetchedData(data);
                })
                /*Show an alert when fetching encounters an error and stop the 
                loader accordingly*/
                .catch(err => {
                    alert("Please insert a valid name")
                    setLoading(false);
                })
        }
    }, dependancies)
    // Returning the data to use them later in displaying the weather
    return [isLoading, fetchedData];
};

И вот как работает мой компонент формы:

 // initialized the input to an empty string
    const [searchTerm, setSearchTerm] = useState('');

    // Initialize the state of submit to false 
    const [isSubmit, setIsSubmit] = useState(false);

    // Use array destruction to get isLoading and fetchedData from the imported userHttp hook
    const [isLoading, fetchedData] = useHttp(`http://api.openweathermap.org/data/2.5/weather?q=${searchTerm}
    &APPID=b8c1572d189de60f5480324c6b53d9ab`, [isSubmit], isSubmit);

    // Use object destruction to get the desired properties out of the fetched data
    const { name, sys, weather, main } = fetchedData ? fetchedData : '';

    // Get the user input in the search bar to pass it to submitInput function
    const getSearchTerm = (e) => {
        setSearchTerm(e.target.value);
    }

    // Submit the userinput and call the custom hook to fetch the data matched with the input
    const submitInput = (event) => {
        // Prevent the form from actually submitting
        event.preventDefault();
        // Change the state of isSubmit so that useEffect can be re-called
        setIsSubmit(!isSubmit);
    }

As Вы можете видеть, что я хотел изменить значение состояния isSubmit всякий раз, когда пользователь отправляет данные, чтобы вызвать useEffect, поскольку «isSubmit» также передается как зависимость. Более того, я создал условие, чтобы useEffect не работал всякий раз, когда приложение отображается, потому что я хочу, чтобы он работал только тогда, когда пользователь отправляет его.

Дело в том, что он работает отлично в первый раз, но когда я ввожу другое значение , Мне нужно дважды щелкнуть по кнопке, чтобы она заработала. Некоторое время я размышлял над этой проблемой, но в конце концов ни к чему не пришел. Надеюсь, кто-нибудь сможет мне с этим помочь. Заранее спасибо.

Вот также ссылка на репорт проекта на GitHub: https://github.com/Saifsamirk/weatherApp

1 Ответ

1 голос
/ 08 мая 2020

Ваш useEffect хук срабатывает, только когда isSubmit = true. Когда вы звоните submitInput, вы меняете только значение isSubmit на !isSubmit. Только true каждый второй раз. Вы можете сбросить свое состояние isSubmit на false после запуска события.

...