Класс React не обновляется при изменении состояния - PullRequest
1 голос
/ 22 января 2020

Я делаю игру, в которой мне нужен другой стиль для выбранного (нажатого) элемента. Я пытаюсь прикрепить «выбранный» класс к div, если по нему щелкают. Другими словами, у меня есть состояние:

const [pressedGifId, gifPressed] = useState(null);

, а когда

pressedGifId === gifId

, тогда я должен присоединить «выбранный» класс к моему div. Вот мой упрощенный код:

import React, { useState, useEffect } from 'react';

export default function Game() {
  const addedToGameGif = [];

  const [pressedGifId, gifPressed] = useState(null);
  const [photoCards] = useState([]);

  useEffect(() => {
    console.log(pressedGifId);
  }, [pressedGifId]);

  if (photoCards.length === 0) {
    for (let i = 0; i < 5; i += 1) {
      addedToGameGif.push([i, 'http://petapixel.com/assets/uploads/2019/06/manipulatedelephant-800x534.jpg']);
    }
  }

  addedToGameGif.map(item =>
    photoCards.push(
      <div key={item[0]}>
        <div
          onClick={() => gifPressed(`gif${item[0]}`)}
          className={`${pressedGifId === `gif${item[0]}` && 'selected'}`}
        >
          <img src={item[1]} alt="bla" width="300" height="180" />
        </div>
        <br />
      </div>,
    ),
  );
  return <div>{photoCards}</div>;
}

Я не вижу, чтобы класс обновлялся в соответствии с состоянием: (он остается нулевым)

f12 view

Но я получаю обновленное состояние в консоли (я печатаю его в использованииEffect):

console view

Моя цель:

1) Изменить состояние (selectedGifId) при нажатии

2) Добавить класс "selected" в div, если selectedGifId соответствует текущему идентификатору элемента (gif${item[0]})

UPDATE2:

Предоставить решение werent работал на меня, так как мои фотокарты были случайным образом выбранными фотографиями и с предоставленными решениями фотографии превращались в новые случайно выбранные фотографии при каждом щелчке (что я не хочу). Но это привело меня к правильному ответу:

Я перевел фотокарточки в состояние (зацепка) и установил его при первой загрузке (когда длина массива фотокарточек равна 0). Это препятствовало перезагрузке, и классы работали.

Вот обновленный код:

    export default function Game(props) {

    const [pressedGifId, setGifPressed] = useState(null);
    const [gifCards, setGifCards] = useState([]);

    useEffect(() => {
        if (gifCards.length === 0) 
          setGifCards(randGen.getGifArray());
    }

      const renderCards = () =>
      gifCards.map((item, index) => {
      const gifId = `gif${item[0]}`;

      return (
        <div key={item[0]}>
          <div
            onClick={() => setGifPressed(gifId)}
            onKeyPress={() => setGifPressed(gifId)}
            role="button"
            tabIndex="0"
            className={`card ${getClass(gifId)}`}
          >
            <img
              src={item[1]}
              alt={txtCards[index][1]}
              width="300"
              height="180"
            />
          </div>
        </div>
      );
    });

     return (
       <div>
          {renderCards()}
        </div>
      );
   }



Ответы [ 2 ]

2 голосов
/ 22 января 2020

Это строка, где я изменился.

className={pressedGifId === `gif${item[0]}` ? "selected" : ""}

Весь код.

import React, { useState, useEffect } from "react";
import "./styles.css";
export default function Game() {
  const addedToGameGif = [];

  const [pressedGifId, gifPressed] = useState(null);
  let photoCards = [];

  useEffect(() => {
    console.log("->", pressedGifId);
  }, [pressedGifId]);

  if (photoCards.length === 0) {
    for (let i = 0; i < 5; i += 1) {
      addedToGameGif.push([
        i,
        "https://petapixel.com/assets/uploads/2019/06/manipulatedelephant-800x534.jpg"
      ]);
    }
  }

  photoCards = addedToGameGif.map(item => (
    <div key={item[0]}>
      <div
        onClick={() => gifPressed(`gif${item[0]}`)}
        className={pressedGifId === `gif${item[0]}` ? "selected" : ""}
      >
        <img src={item[1]} alt="bla" width="300" height="180" />
        {console.log(item)}
      </div>
      <br />
    </div>
  ));

  console.log("-", photoCards, addedToGameGif);
  return <div>{photoCards}</div>;
}

Это работает. Я пытался проверить это JS фрагмент

2 голосов
/ 22 января 2020
import React, { useState, useEffect } from 'react';

const Game = () => {

  //here we are passing our gif data 
  const gifData = [
    'http://petapixel.com/assets/uploads/2019/06/manipulatedelephant-800x534.jpg',
    'http://petapixel.com/assets/uploads/2019/06/manipulatedelephant-800x534.jpg',
    'http://petapixel.com/assets/uploads/2019/06/manipulatedelephant-800x534.jpg',
    'http://petapixel.com/assets/uploads/2019/06/manipulatedelephant-800x534.jpg',
    'http://petapixel.com/assets/uploads/2019/06/manipulatedelephant-800x534.jpg' 
  ]

  // pressedGifId : for gifId selection
  const [pressedGifId, setGifPressed ] = useState(0);

  // renderPhotoCards : this function return all cards 
  // onClick :   setGifPressed to clicked gifId 
  // className : if our index of perticuler gif match with pressedGifId then we are setting it as selected

  const renderPhotoCards = () => 
    gifData.map(( item , index )  => (
      <div key={index}>
        <div
          onClick={() => setGifPressed(index)}
          className={  pressedGifId === index ? `gif${index} selected` : `gif${index}`  }
        >
          <img src={item} alt="bla" width="300" height="180" />
        </div>
        <br />
      </div>
    )
  )

  return renderPhotoCards()

}

export default Game;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...