Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

197
Views
Delay in useEffect setting the setState value

I have this component that renders the number of people that liked the book, however I cant get consistent result in my states.

Heres my code:


///this is for getting the book details


  
const {id} = useParams();
const dispatch = useDispatch();
const[hasliked, sethasliked] = useState(null);

  useEffect(() => {
    const bookData = {
           id: id
        }
    dispatch(openBook(bookData))   
 }, [])

///and this is for setting the state of the component

const { bookFeatured, isLoading, isSuccess, openbook, likeStatus } = useSelector(state => state.book);
const { user, isError, message } = useSelector(state => state.auth);

  useEffect(()=>{


    if(openbook.noOfLikes?.find((noOfLikes) => noOfLikes === user._id)){

      sethasliked(true)

    }else{
      sethasliked(false)
    }


},[openbook])


  const Likes = () => {
   
      return hasliked
        ? (
          <><FaHeart fontSize="small"  />&nbsp;{hasliked.toString()}</>
        ) : (
          <><FaRegHeart  fontSize="small" fill='white'/>&nbsp;{hasliked.toString()}</>
        );
  };

the thing here is i get inconsistent result when getting the value from const hasliked, if i already liked a book, it will sometimes tell me that the hasliked is false, but sometimes it will go to true, this caused me to get different result each time i render the component, I think it has something to do with the delay in useEffect due to async actions, Is there something that I can do about this?

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

  1. you are trying to render a boolean value with a .toString()? why not just do
   
      return hasliked
        ? (
          <><FaHeart fontSize="small"  />True</>


seeing as how hasliked is already true there.


  1. this
else{
      sethasliked(false)
    }

can be eliminated by changing the init to

const[hasliked, sethasliked] = useState(false);


  1. if your dispatch(openBook(bookData)) is returning a promise you can set hasliked in a .then block eliminating the need for a second useeffect

  1. change the return from this
return hasliked

to this

return hasliked && openbook

about 4 years ago · Juan Pablo Isaza Report

0

You can add a loading state to your component and check if the loading state is true then show a loader or else show your component.

const {id} = useParams();
const dispatch = useDispatch();
const[hasliked, sethasliked] = useState(null);
const [loading, setLoading] = useState(false) // The loading state

  useEffect(() => {
    setLoading(true) // Setting the loading state true
    const bookData = {
           id: id
        }
    dispatch(openBook(bookData))   
 }, [])

///and this is for setting the state of the component

const { bookFeatured, isLoading, isSuccess, openbook, likeStatus } = useSelector(state => state.book);
const { user, isError, message } = useSelector(state => state.auth);

  useEffect(()=>{    
    if(openbook.noOfLikes?.find((noOfLikes) => noOfLikes === user._id)){
      sethasliked(true)
      setLoading(false) // Setting loading state to false
    }else{
      sethasliked(false)
      setLoading(false) // Setting loading state to false
    }
},[openbook])


  const Likes = () => {
      // show a loader if loading is true
      if(loading) {
        return <div>Loading...</div>
      }   

      return hasliked
        ? (
          <><FaHeart fontSize="small"  />&nbsp;{hasliked.toString()}</>
        ) : (
          <><FaRegHeart  fontSize="small" fill='white'/>&nbsp;{hasliked.toString()}</>
        );
  };
about 4 years ago · Juan Pablo Isaza Report

0

Have you tried using setTimeout?

useEffect( () => {
  const tmr = setTimeout( () => { 
    const bookData = { id: id }
    dispatch( openBook(bookData) )
  }, 500)
  return () => clearTimeout(tmr);
 }, [])

useEffect( () => {
  const tmr = setTimeout( () => { 
    if (openbook.noOfLikes?.find( (noOfLikes) => noOfLikes === user._id) ) {
      sethasliked(true)
    } else { sethasliked( false) }
  }, 500)
  return () => clearTimeout(tmr);
},[openbook])

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!