1
votes

Manipulation dynamique du nom de classe dans React

J'ai un problème avec le changement de classe dynamique dans mon composant de réaction. Dans un simple curseur, je veux afficher uniquement l'image sélectionnée. Mon composant ressemble à ceci:

import React, { useState } from 'react';

import './Slider.scss';

import SliderImage from './SliderImage';

import photo1 from '../../../Images/photo1.jpg';
import photo2 from '../../../Images/photo2.jpg';
import photo3 from '../../../Images/photo3.jpg';
import photo4 from '../../../Images/photo4.jpg';
import photo5 from '../../../Images/photo5.jpg';

function Slider() {
  let slideArr = [
    {
      id: 1,
      src: photo1,
      text: 'Far far away, behind the word mountains',
      alt: 'wedding_photo',
    },
    {
      id: 2,
      src: photo2,
      text: 'Far far away, behind the word mountains',
      alt: 'wedding_photo',
    },
    {
      id: 3,
      src: photo3,
      text: 'Far far away, behind the word mountains',
      alt: 'wedding_photo',
    },
    {
      id: 4,
      src: photo4,
      text: 'Far far away, behind the word mountains',
      alt: 'wedding_photo',
    },
    {
      id: 5,
      src: photo5,
      text: 'Far far away, behind the word mountains',
      alt: 'wedding_photo',
    },
  ];
  const [x, setX] = useState(0);
  const goLeft = () => {
    console.log(x);
    x === 0 ? setX(-100 * (slideArr.length - 1)) : setX(x + 100);
  };
  const goRight = () => {
    console.log(x);
    x === -100 * (slideArr.length - 1) ? setX(0) : setX(x - 100);
  };

  return (
    <div className='Slider'>
      {slideArr.map((item) => {
        return (
          <div
            className={`Slider__Slide + ${item.id - 1 === x ? 'active' : ''}`}
            key={item.id}
            style={{ transform: `translateX(${x}%)` }}>
            <SliderImage
              classTxt={'Slider__Slide-txt'}
              classImg={'Slider__Slide-img'}
              src={item.src}
              text={item.text}
              alt={item.alt}
            />
          </div>
        );
      })}

      <button id='goLeft' onClick={goLeft}>
        left
      </button>
      <button id='goRight' onClick={goRight}>
        right
      </button>
    </div>
  );
}

export default Slider;


J'ai donc un tableau avec des photos, qui ont des identifiants. Basé sur Id, je montre une image dans le composant SliderImage. Cette partie fonctionne bien. Les images changent, mais je suis incapable de changer de manière dynamique les noms de classe

Ici, je veux changer la classe className={`Slider__Slide + ${item.id - 1 === x ? 'active' : ''}`} mais onClick n'ajoute pas d' active à la nouvelle image.

Merci pour toute aide


1 commentaires

J'ai décidé de laisser tomber les crochets et de simplement faire un composant de classe. Il m'a fallu environ 15 minutes pour que cela fonctionne comme je le souhaite. Merci à tous pour l'aide


3 Réponses :


0
votes

C'est fondamentalement une question de concaténation de chaînes. L'expression JSX que vous avez a des espaces et un + comme texte dans un littéral de modèle. Utilisez + avec des littéraux de chaîne ou utilisez un littéral de modèle, mais pas les deux.

Utilisation de littéraux de chaîne:

className={`Slider__Slide ${item.id - 1 === x ? "active" : ""}`}

Utilisation d'un modèle littéral:

className={"Slider__Slide " + (item.id - 1 === x ? "active" : "")}


2 commentaires

Salut. Merci, mais cela ne fonctionne pas non plus. Le modèle littéral n'ajoute rien. La classe est active uniquement sur la première photo


@shivetay - Alors item.id - 1 n'est pas === x . En regardant votre code, vous changez x d'une manière qui semble être très éloignée des valeurs d' id vous avez affichées (en ajoutant / en soustrayant 100 ). Vous devez vous assurer que x est uniquement les valeurs 0 à 4 (avec le code que vous avez montré). Ce qui précède la sortie correctement active lorsque x a une valeur correspondante.



2
votes

Vous utilisez des chaînes littérales d'une manière comme si vous concaténiez deux chaînes. Tout ce qui se trouve à l'intérieur des graduations arrière sera tel quel s'il ne s'agit pas de variables.

const item = {
  id: 3
};

const x = 2;

const classes = classNames({ firstClassName: true, bar: item.id - 1 === x });

console.log(classes)  // => 'className active'

Ici, vous utilisez le signe plus et il sera classname + active lorsqu'il sera évalué, ce que vous voulez faire est essentiellement de supprimer le signe plus.

  className={`Slider__Slide ${item.id - 1 === x ? 'active' : ''}`}

Je vous suggère d'utiliser la bibliothèque de noms de classes pour de tels cas d'utilisation lorsque vous devez effectuer un chaînage conditionnel pour les classes. L'exemple suivant montre comment ce serait, disons que notre objet item ressemble à ce qui suit et que x est défini de manière à être évalué à true.

  className={`Slider__Slide + ${item.id - 1 === x ? 'active' : ''}`}


0 commentaires

0
votes

Je suggérerai deux choses

  1. Changer la signification de 'x' pour être l'identifiant actuel au lieu de la position

  2. Remplacez le "+" du modèle de chaîne, car il donne un littéral "+" Slider__Slide + ${item.id - 1 === x ? 'active' : ''} => "Slider__Slide + active" ou "Slider__Slide +"

          <div
            className={`Slider__Slide${item.id - 1 === x ? 'active' : ''}`}
            key={item.id}
            style={{ transform: `translateX(${x * (-100}%)` }}>
            <SliderImage
              classTxt={'Slider__Slide-txt'}
              classImg={'Slider__Slide-img'}
              src={item.src}
              text={item.text}
              alt={item.alt}
            />
          </div>
    

au retour

   const [x, setX] = useState(0);

   const goLeft = () => {
     console.log(x);
     x === 0 ? setX(slideArr.length - 1) : setX(x);
   };

    const goRight = () => {
      console.log(x);
      x === (slideArr.length - 1) ? setX(0) : setX(x);
    };


0 commentaires