0

I am trying to make a like/unlike button and for this purpose, I use a react hook name liked initialised to false.

this hook is used to modify the like button in front and the like event in back-end. The problem is that setState is an asynchron function and I cannot have the good state of liked to perform my actions.

I already tried with a useEffect but with liked initialised to false, the action when liked === false is performed on loading. I don t want to.

here is my code

import React from 'react'
import styled from 'styled-components'
import HeartIcon from 'client/components/icons/Heart'
import IconButton from 'client/components/IconButton'
const Heart = styled(HeartIcon)`
  stroke: ${p => p.theme.primary};
  stroke-width: 2;
  fill: transparent;
  transition: fill 300ms;
  display: block;
  width: 100%;
  height: auto;
  &[aria-checked='true'] {
    fill: ${p => p.theme.primary};
  }
`
export default function LikeButton(props) {
    const [liked, setLiked] = React.useState(false)
    function onLikeChange() {
      setLiked(prevLiked => !prevLiked)
      if (liked === true) {
        // creation d'un event like
        console.log('like')
      } else {
        console.log('unlike')
        // destroy l'event du like existant
      }
    }
    return (
      <IconButton onClick={onLikeChange} {...props}>
        <Heart aria-checked={liked} />
      </IconButton>
    )
}

of course I can switch my actions to perform what I want but I prefere to understand what I'm doing because I'm new to react ;)

What is the way ? Thank you

user7430961
  • 35
  • 1
  • 6
  • 1
    Does something like [this](https://stackoverflow.com/a/53254028/9381601) work? This will let you track the first render and decide not to execute the rest of your code when needed. – Brian Thompson Nov 27 '19 at 17:49

1 Answers1

1

I think what you are trying to accomplish here needs two useEffect hooks. One for getting the value from the backend on initial load and one for updating the value when it changes. For this you should use two useEffect hooks. The difference between these is quite simple. The hook for setting the initial value is for when your component needs to do something after render, and the hook for setting the liked value when it the state changes is only called when liked changes. Therefor you pass an array as an optional second argument to useEffect.

const [liked, setLiked] = useState()

useEffect(() => {
  console.log('get the initial value of liked from backend');
  setLiked(initialValue)
}

useEffect(() => {
  console.log('Do something after liked has changed', liked);
  if (liked === true) {
    console.log('like')
  } else {
    console.log('unlike')
  }
}, [liked]);

function onLikeChange() {
  setLiked(prevLiked => !prevLiked)
}

Jurrian
  • 850
  • 6
  • 20