Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React hooks rendering component before useEffect finishes

I have an asynchronous request in my useEffect. I notice that the component is rendered before the useEffect finishes.

import React, { useEffect } from 'react';
import axios from 'axios';

import './SearchWords.css';

const URL_REQUEST = 'http://myLink.com';

const SearchWords = (props) => {
    const { setState } = props;

    useEffect(async () => {
        const data = {
            sentence: props.sentence
        };
      
        await axios.post(`${URL_REQUEST}/getData`, { data })
            .then((res) => {
                setState(state =>({
                    ...state,
                    search: res.data
                }));
            })
            .catch((err) =>{
                console.log(err);
            })
    }, []);

    const render = () => {
        if(props.search.length > 0) {
            const linkMarkup = props.search.map((link) => (
                <li key={link.id} className="link-list-item">
                  <a
                    href={link.link}
                    target="_blank"
                    rel="noopener noreferrer"
                    className="link-list-item-url"
                    onClick
                  >
                    {link.name}
                  </a>
                </li>
            ));
            
            return <ul className="link-list">{linkMarkup}</ul>;
        } else {
            return <p>No data found for: {props.sentence}</p>
        }
    }

    return render()
}

export default SearchWords;

It is working, but it first shows No data found for: My Search String. Then, it reloads and shows the <ul> with the results. How can I avoid it to first show the "No data found" message.

Thanks

like image 381
myTest532 myTest532 Avatar asked Jun 20 '26 02:06

myTest532 myTest532


1 Answers

The simplest tweak would be to conditionally render that section of the JSX depending on whether the response has come back yet:

const [hasLoaded, setHasLoaded] = useState();
// ...
.then((res) => {
    setState(state =>({
        ...state,
        search: res.data
    }));
    setHasLoaded(true);
})

then change

return <p>No data found for: {props.sentence}</p>

to

return hasLoaded ? <p>No data found for: {props.sentence}</p> : <p>Loading...</p>;
like image 71
CertainPerformance Avatar answered Jun 21 '26 15:06

CertainPerformance



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!