Home > OS >  How to implement react icon properly with useState hook?
How to implement react icon properly with useState hook?

Time:06-07

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>
  );
}

CodePudding user response:

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

CodePudding user response:

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); 
}, []);
  • Related