Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

200
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda