1

On React, I attempted making a feature to let user can see active feedback on screen by changing its icon when they click it.

How can I let it change to another icon (e.g. from Box to BoxChecked) once I click it?

note: I know this code line is the problem...(sob)

<img src={click} alt="icon" onClick={handleClick} />

App.jsx

import React, { useState } from 'react'
import './App.css'
import { GrCheckbox as Box }  from 'react-icons/gr'
import { GrCheckboxSelected as BoxChecked } from 'react-icons/gr' 

export default function App() {
  const [icon, setIcon] = useState(false);
  const [click, setClick] = useState(Box);
  
  function handleClick() {
    setIcon(!icon); 
    icon ? setClick(Box) : setClick(BoxChecked);
  }
  return (
    <div className="App">
        <img src={click} alt="icon" onClick={handleClick} />
        <p>Clicked {click} times</p>
    </div>
  );
}
mireumireu
  • 705
  • 1
  • 7
  • 9

2 Answers2

1

useState is async so you don't have the value of icon immediately after the execution of setIcon in your handler. You need to put the setClick call in a useEffect hook:

React.useEffect(() => {
    icon ? setClick(Box) : setClick(BoxChecked);
}, [icon]);

function handleClick() {
    setIcon(!icon); 
}

This effect will be executed when icon changes because it is added to the useEffect's dependency array. Have a look at the docs for more info: https://reactjs.org/docs/hooks-effect.html

A. Llorente
  • 1,142
  • 6
  • 16
1

Storing a component in state is not recommended. Use condition to set src.

    <img src={icon ? Box : BoxChecked} alt="icon" onClick={handleClick} />

Change handler to this

function handleClick() {
    setIcon(prevIcon => !prevIcon); 
}

or better

const handleClick = useCallback(() => {
      setIcon(prevIcon => !prevIcon); 
}, []);
kiranvj
  • 32,342
  • 7
  • 71
  • 76
  • 1
    I think this is the correct answer and you could remove all the click related code, in my answer I explained why it was not working, but if you should follow any approach I would go for @kiranvj suggestion – A. Llorente Jun 07 '22 at 09:48