Search code examples
reactjsasync-awaitreact-hooksuse-effectreact-state

(React Hooks): one setstate is not working, but double setstate is working?


this is my code:

function Users() {

    const [users, setUsers] = useState([]);
    const [loading, setLoading] = useState(false);

    useEffect(() => {

        const getUsersData = async () => {
            setLoading(true);

            const response = await fetch('https://api.github.com/users');
            const data = await response.json();

            setUsers([...data]);

            setLoading(false);
        }

        getUsersData();

    }, [users])

    return (
        <div className="container my-4">
            <div className="row">
                {loading ? (
                    <p>loading...</p>
                ) : (
                    users.map((user) => <UserItem key={user.id} user={user}/>)
                )}
            </div>
        </div>
    )
}

after setUsers, setLoading(false) is notworking.

in the chrome developer tools, loading state is still "true" not "false".

if i using double setLoading(false) its work, loading state is "false" now. like this:

useEffect(() => {

        const getUsersData = async () => {
            setLoading(true);

            const response = await fetch('https://api.github.com/users');
            const data = await response.json();

            setUsers([...data]);

            setLoading(false);
            setLoading(false);
        }

        getUsersData();

    }, [users])

why 1 setLoading not working but 2 setLoading is working ?


Solution

    1. in map method you are reading whole object as name instead you should read one property user={user.login}
    2. call setLoading(false) after calling getUsersData()
    3. in useEffect users dependency not needed

    here is working code

    function App() {
    
                  const [users, setUsers] = useState([]);
                  const [loading, setLoading] = useState(false);
    
                  useEffect(() => {
                    const getUsersData = async () => {
                      setLoading(true);
    
                      const response = await fetch("https://api.github.com/users");
                      const data = await response.json();
    
                      setUsers([...data]);
                    };
                    getUsersData();
                    setLoading(false);
                  }, []);
    
                  return (
                    <div className="container my-4">
                      <div className="row">
                        {loading ? (
                          <p>loading...</p>
                        ) : (
                          users.map(user => <UserItem key={user.id} user={user.login} />)
                        )}
                      </div>
                    </div>
                  );
                }