javascript 如何在Reactjs中动态更改现有元素的类名

aelbi1ox  于 2023-05-16  发布在  Java
关注(0)|答案(1)|浏览(210)

我正在构建一个简单的记忆游戏,我想通过修改现有元素的类名来指示玩家猜测正确/不正确的答案,使它们 Flink 绿色或红色,我目前只是将“正确”和“错误”打印到控制台。
下面是一个函数,它渲染我想要 Flink 绿色/红色的元素:

const renderMajorSegment = (musicKey, index) => {
    let arc = calculateArc(outerRadius, innerRadius, musicKey.segmentMetadata.startAngle, musicKey.segmentMetadata.endAngle);
    let [arcCenterX, arcCenterY] = arc.centroid();

    return <g className={`circle-segment ${musicKey.segmentMetadata.majorCircle.isVisible ? 'isVisible': ''}`} 
              key={index}>
            <path 
              d={arc.apply()} // apply() is needed to generate the string that goes into the 'd' attribute
            />
            <text x={arcCenterX} y={arcCenterY} transform={`rotate(15, ${arcCenterX}, ${arcCenterY})`}>
              {abbreviateKeyFromChord(musicKey.chords[0])}
            </text>
          </g>
  }

以下是我的功能组件的主要部分:

return (
    <div className='circle-of-fifths-container'>
      <svg
        height={diameter*1.1}
        width={diameter*1.1}>
        <g className='circle-container' transform={`translate(${diameter/2 + 25},${diameter/2 + 25}) rotate(-15)`}>
          <circle r={outerRadius} className='base-circle'/>
          <g className='outer-circle-segments-container'>
            {musicKeysObject.map((musicKey, index) => renderMajorSegment(musicKey, index))}
          </g>
          <g className='inner-circle-segments-container'>
            {musicKeysObject.map((musicKey, index) => renderMinorSegment(musicKey, index))}
          </g>
          {mode === READY && 
            <g id='play-button-container' onMouseUp={startRound}>
              <circle r={innerRadius2} id='play-button'/>
              <text id='play-button-text' transform='rotate(15)'>PLAY GAME</text>
            </g>}
        </g>
      </svg>
      {mode === PLAYING &&
        <input placeholder='Your answer' onKeyDown={handleUserInput}></input>
      }
    </div>
  )

我还没有真正尝试过什么,我只是在思考这个问题,并提出一些解决方案。
我的第一个想法是给renderMajorSegment()函数添加一个参数,它可以根据正确/错误的答案接受一个字符串,然后根据这个答案修改类名。
在Google上搜索了一番之后,我发现我可以在state中存储一些东西,然后根据state的值修改元素的类。在这种情况下,我将修改状态的值,我将只能引用renderSegmentMajor()函数中的状态值,并执行类似于我已经对isVisible值所做的操作。
这是我的函数,它将处理逻辑并导致类名更改(当用户提交答案时):

const handleUserInput = (event) => {
    var index;
    if (hiddenSegment.major) {
      index = 0;
    } else {
      index = 5;
    }

    if (event.key === 'Enter') {
      if (event.target.value === abbreviateKeyFromChord(hiddenSegment.chords[index])) {
        console.log('CORRECT');
        // Set both major and minor circles to true
        // 1 will already be true so it makes no difference, sets the non-visible one to true
        hiddenSegment.segmentMetadata.majorCircle.isVisible = true;
        hiddenSegment.segmentMetadata.minorCircle.isVisible = true;

        // Modify the css classes to make the segments go green

        startRound();
      } else {
        // Modify the css classes to make the segments go red
        console.log('WRONG');
      }
    }
  };
6ie5vjzr

6ie5vjzr1#

我认为useState是实现我在这里想要的功能的好方法,这是正确的。
下面是我的useState钩子和我可以用于这个钩子的2个值:

const CORRECT = 'correct';
const WRONG = 'wrong';
const [userAnswer, setUserAnswer] = useState(null);

然后,我可以根据useState的值修改className。我使用classnames utility来简化这一点,并使代码更清晰

var segmentClasses = classNames(
      'circle-segment',
      {'isVisible': musicKey.segmentMetadata.majorCircle.isVisible},
      {'correctAnswer': userAnswer === CORRECT},
      {'wrongAnswer': userAnswer === WRONG}
    );

    return <g className={segmentClasses} key={index}>
            <path 
              d={arc.apply()} // apply() is needed to generate the string that goes into the 'd' attribute
            />
            <text x={arcCenterX} y={arcCenterY} transform={`rotate(15, ${arcCenterX}, ${arcCenterY})`}>
              {abbreviateKeyFromChord(musicKey.chords[0])}
            </text>
          </g>

相关问题