2

i need to toggle some css effect when one of the images of the list is clicked (but only in the image that was clicked). I did this but is not working.

I'm trying to do it using "classList.toggle('selected')", but the css doesn't change. I don't know if there is some way to do it with 'useState'.

I'm learning reactjs, i hope someone can help.

REACTJS

const Photos = () =>{

  const[mainPhoto, setMainPhoto] = useState(Barco)

  const changePhoto = (element) => {
    setMainPhoto(element.target.src)
    let target = element.currentTarget;
    target.classList.toggle('selected')
  }

  return(
      <section className={styles.sectionContainer}>
        <div className={styles.imgContainer}>
          <img src={mainPhoto}/>
        </div>
        <div className={styles.titleContainer}>
          <div className={styles.infoArea}>
            <h1>LOren </h1>
            <p className={styles.resume}>LOren</p>
            <p className={styles.about}>LOren LOren LOren LOrenLOrenLOrenLOren LOrenLOren LOren LOren LOren LOrenLOren
            LOren LOrens
            </p>
            <h2>Fotografia:</h2>
            <ul>
              <li>User 01</li>
              <li>User 02</li>
            </ul>
          </div>
          <div className={styles.photoArea}>
            <div>
              <img onClick={ (e) => changePhoto(e)} src={Surf}/>
              <img onClick={ (e) => changePhoto(e)} src={Barco}/>
              <img onClick={ (e) => changePhoto(e)} src={Barco}/>
              <img onClick={ (e) => changePhoto(e)} src={Barco}/>
              <img onClick={ (e) => changePhoto(e)} src={Barco}/>
              <img onClick={ (e) => changePhoto(e)} src={Barco}/>
              <img onClick={ (e) => changePhoto(e)} src={Barco}/>
              <img onClick={ (e) => changePhoto(e)} src={Barco}/>
              <img onClick={ (e) => changePhoto(e)} src={Barco}/>
              <img onClick={ (e) => changePhoto(e)} src={Barco}/>
              <img onClick={ (e) => changePhoto(e)} src={Barco}/>
            </div>
          </div>
        </div>
      </section>
  )
}

export default Photos

SCSS

img {
  height: 100%;
  width: 100%;
  cursor: pointer;
  object-fit: cover;

  &:hover {
    filter: blur(1px);
  }

  &.selected {
    border: 1px solid black;
  }

}      

2 Answers 2

1

You should absolutely use and change state to cause changes to the DOM. In React, never use native DOM methods like classList.toggle.

For this case, use a numeric index state of the index of the selected image. First have an array of srcs, eg

const srcs = [Surf, Barco, ...]

Then map over them, with a click handler that uses the iteration index to decide how to change the selected index in state:

const [indexSelected, setIndexSelected] = useState(-1);
const handleClick = i => () => {
  setIndexSelected(i === indexSelected ? -1 : indexSelected);
};
// ...
  <div className={styles.photoArea}>
    <div>
      {
        srcs.map((src, i) => <img
          onClick={handleClick(i)}
          className={i === indexSelected ? 'selected' : ''}
          src={src}
        />)
      }
    </div>
Sign up to request clarification or add additional context in comments.

3 Comments

First of all, thank you for the answer. I tried your code but it did'nt work. Nice to know that i should do it with "state".... So, i will try to do something.
What do you mean "didn't work"? Can you explain what the problem you encounter is?
I had to make some changes to make it work. But your answer helped me a lot. I will post here what i did. Thanks again.
0

I made it work by doing some changes.

REACT

const Photos = () =>{

  const[mainPhoto, setMainPhoto] = useState(Barco)
  const[selected, setSelected] = useState(0)

  const changePhoto = (element, index) => {
    setMainPhoto(element.target.src)
    setSelected(index)
  }

  const images = [Barco, Surf]

  return(
      <section className={styles.sectionContainer}>
        <div className={styles.imgContainer}>
          <img src={mainPhoto}/>
          <button className={styles.previous} >
            <GrPrevious size={24} />
          </button>
          <button className={styles.next}>
            <GrNext size={24}/>
          </button>
        </div>
        <div className={styles.titleContainer}>
          <div className={styles.infoArea}>
            <h1>LOren </h1>
            <p className={styles.resume}>LOren</p>
            <p className={styles.about}>LOren LOren LOren LOrenLOrenLOrenLOren LOrenLOren LOren LOren LOren LOrenLOren
            LOren LOrens
            </p>
            <h2>Fotografia:</h2>
            <ul>
              <li>Guilherme Donada</li>
              <li>Guilherme Do nada</li>
            </ul>
          </div>
          <div className={styles.photoArea}>
            <div>
            {images.map((image,index) => (              
              <img 
                key={index}
                onClick={ (e) => changePhoto(e, index)}  
                src={image} 
                className={ index == selected ? styles.selected : '' }
              />
            ))}
            </div>
          </div>
        </div>
      </section>
  )
}

export default Photos

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.