Home > OS >  React state is updated only the second time I click on the button
React state is updated only the second time I click on the button

Time:11-10

I am trying to fetch data from my Express api which is working, but there is issue in the frontend, it seems like when I change the input state there is a delay even if I call the functions the fetch data after updating the input state.

Here is my component:

import React, { useState, useEffect } from 'react';
import UsersList from './UsersList.js';

function SearchBox() {

    const [input, setInput] = useState("");
    const [githubUserResult, setGithubUserResult] = useState([]);
    const [gitlabUserResult, setGitlabUserResult] = useState([]);
    const [isLoaded, setIsloaded] = useState(false);
    const [error, setError] = useState(null);

    const handleInputChange = (e) => {
        setInput(e.target.value);
    }

    const searchUser = async (e) => {
        e.preventDefault();
        searchUserOnGithub(input);
        searchUserOnGitLab(input);
        setIsloaded(true);
    }

    const searchUserOnGithub = async (username) => {
       await fetch(`/api/github/userinfo/${username}`, {
            method: "GET", headers: {
                "Content-Type": "application/json",
            }
        })
            .then(res => res.json())
            .then(
                (result) => {
                    setGithubUserResult(result);
                    console.log(githubUserResult);
                },
                (error) => {
                    setError(error)
                })
    }

    const searchUserOnGitLab = async (username) => {
       await fetch(`/api/gitlab/userinfo/${username}`, {
            method: "GET", headers: {
                "Content-Type": "application/json",
            }
        })
            .then(res => res.json())
            .then(
                (result) => {
                    setGitlabUserResult(result);
                    console.log(gitlabUserResult);
                },
                (error) => {
                    setError(error)
                })
    }

    if (error) {
        return <div>Error: {error.message}</div>;
    }return (
        <div className='search-container'>
            <form>
                <input type="text" onChange={handleInputChange} />
                <button type="button" onClick={searchUser} >Search</button>
            </form>
            <h3>github</h3><br />
            {/*isLoaded ? <UsersList users={githubUserResult} />: ''*/}
            <h3>gitLab</h3><br />
            {/*isLoaded ? <UsersList users={gitlabUserResult} /> : ''*/}
        </div>
    )

}

export default SearchBox;

On the console we can see the first attempt failling(first click), and the second one working: enter image description here

CodePudding user response:

You are logging your states, and your states will not update until the the next render. When you click on the button the following code is executed:

    setGithubUserResult(result);
    console.log(githubUserResult);

See Closures.

result is the value returned from your request, but githubUserResult has the initial value you declared for the state, which is an empty array. Your state (githubUserResult) does not update synchronously and immediately when you set the state. Hence the stale value of the state.

If you want to access the updated value, one way would be to use the result not the state directly.

  • Related