【问题标题】:Changing the output of a .map depending on the value根据值更改 .map 的输出
【发布时间】:2020-06-04 23:20:14
【问题描述】:

我的标题可能没有多大意义,但基本上我想要实现的是

每次我的 .map 运行时。我希望它在那之后的下一次迭代中吐出常规的“星”,我希望它吐出“左星”。

我正在创建一个评级组件,并决定通过使用半星来作弊,并在每次需要时将其翻转。所以基本上我有星星的“切片”。但我不确定如何使用 .map 或者是否可以使用 .map

另外,如果你能告诉我如何让它保持它的价值。就像第一个“星”是 0.5,那么“左星”是 1,依此类推。

import React, { useState } from 'react'
import {FaStarHalf} from "react-icons/all";
import './Rater.css'


const Rater = () => {
    const [rating, setRating] = useState(null)
    const [hover, setHover] = useState(null)
    const [value] = useState(100)
    const [iconValue, setIconValue] = useState(5)


    return (
        <div>
            <select onChange={(e) =>
            {setIconValue(Number(e.target.value))}}>
                { Array.from(new Array(value),(value, index) =>
                    index + 1).map(value => <option
                    key={value} value={value}>{value}</option>) }
            </select>
            <h1> Select Amount of Icons </h1>

            {[... Array(iconValue)].map((icon, i) => {
                const value = i + 1

                return (
                    <label>
                        <input type='radio'
                           name='rating'
                           value={value}
                           onClick={() => setRating(value)}
                        />
                        <FaStarHalf
                            className='star'
                            color={value <= (hover || rating) ? '#ffc107' : '#e4e5e9'}
                            size={100}
                            onMouseEnter={() => setHover(value)}
                            onMouseLeave={() => setHover(null)}
                        />
                    </label>
                )
            })}
            {[... Array(iconValue)].map((icon, i) => {
                const value = i + 1

                return (
                    <label>
                        <input type='radio'
                            name='rating'
                            value={value}
                            onClick={() => setRating(value)}
                        />
                        <FaStarHalf
                            className='star-left'
                            color={value <= (hover || rating) ? '#ffc107' : '#e4e5e9'}
                            size={100}
                            onMouseEnter={() => setHover(value)}
                            onMouseLeave={() => setHover(null)}
                        />
                    </label>
                )
            })}
        </div>
    )

}

export default Rater

【问题讨论】:

  • 你是说你想要一个在'star'和'star-left'类名之间交替的单一地图操作吗?或者它是一个允许半星的星级评级系统,即评级 3.4 是 3 颗实心,3.5 是 3 颗实心和 1 个半颗星?
  • @DrewReese 我只想让它交替出现。我没有考虑使用不同的地图操作。这可能是一个更好的主意。我想要这个的原因是因为似乎每次我将鼠标悬停在第一个“星”上时,第一个“左星”也会突出显示。就像他们共享相同的价值一样。但我没想到这可能是因为他们确实这样做了。有 2 个单独的地图操作会解决这个问题吗?
  • 您目前拥有的不是 2 个单独的地图操作吗?这就是让我失望的原因,这对我来说没有任何意义。您使用className="star" 映射一次,然后使用className="star-left" 对相同数据进行第二次映射。你有你要做什么的照片吗?
  • @DrewReese 让我再次解释一下,因为我似乎也在自暴自弃。这是我目前拥有的代码。我不确定如何实现这一点,但我不在乎是否使用 2 个地图操作。我只是向您展示了我拥有的所有代码。我希望它以某种方式迭代'star','star-left,'star'......等等。我不确定如何在 React 中做到这一点。我正在使用地图操作,因为这就是输出星形图标的内容。我不在乎逻辑,我只想朝着正确的方向前进。
  • 我猜你可以只检查迭代中的 i 是偶数还是奇数。然后,如果奇数 => 星,如果偶数 => 星-左;根据您要开始的顺序。您可以通过检查 i%2 === 0(偶数)和 i%2 === 1(奇数)来确定这一点。还是我在这里遗漏了什么?

标签: javascript reactjs react-functional-component


【解决方案1】:

在初始数组上加倍并按原样映射(删除第二个数组和映射),但在数组索引上使用模数 2 来确定偶数/奇数并相应地设置交替类名。 i % 2 === 0 是偶数,i % 2 !== 0 是奇数。

className={i % 2 ? "star-left" : "star"}

组件

const Rater = () => {
  const [rating, setRating] = useState(null);
  const [hover, setHover] = useState(null);
  const [value] = useState(100);
  const [iconValue, setIconValue] = useState(5);

  return (
    <div>
      <select
        onChange={e => {
          setIconValue(Number(e.target.value));
        }}
      >
        {Array.from(new Array(value), (value, index) => index + 1).map(
          value => (
            <option key={value} value={value}>
              {value}
            </option>
          )
        )}
      </select>
      <h1> Select Amount of Icons </h1>

      {[...Array(iconValue), ...Array(iconValue)].map((icon, i) => {
        const value = i + 1;

        return (
          <label>
            <input
              type="radio"
              name="rating"
              value={value}
              onClick={() => setRating(value)}
            />
            <FaStarHalf
              className={i % 2 ? "star-left" : "star"}
              color={value <= (hover || rating) ? "#ffc107" : "#e4e5e9"}
              size={100}
              onMouseEnter={() => setHover(value)}
              onMouseLeave={() => setHover(null)}
            />
          </label>
        );
      })}
    </div>
  );
};

注意:由于您将数组翻倍,因此实际评级值是 state 中设置值的一半。

我没有你的样式表,所以这是一个快速/粗略的演示

【讨论】:

  • 天哪,我忘了我可以用吗?和:在类名中。 Ughh 非常感谢老板,我会给你答案的东西,这样你就可以得到更多的分数。 ~ 有什么技巧可以让 css 尽可能地靠近吗?我隐藏了单选按钮。如果你愿意,我可以再发一个帖子,你也可以回答。我的 CSS 很糟糕
  • @4156 我只是猜到你翻转了其中一些,但一个潜在的问题是星星仍然占据它们的正常图标空间,所以当你将内侧对接在一起时,它们会在某些地方重叠,这可能会干扰悬停/鼠标悬停。您可能需要将 FA 图标放置在溢出隐藏多余的容器中然后将容器移动到您需要它们的位置。是的,这超出了这个问题的范围。如果你打开一个新问题,你可能会得到更多的关注。 (还是在这里分享一个链接
  • stackoverflow.com/questions/62200257/… 是新问题的链接。我也添加了 CSS 代码。我想我从上面明白你的意思,但是当我现在可以修复它时,我不想掉进兔子洞。
猜你喜欢
  • 2020-01-08
  • 1970-01-01
  • 1970-01-01
  • 2015-04-20
  • 1970-01-01
  • 1970-01-01
  • 2014-03-18
  • 2021-02-27
  • 2019-01-30
相关资源
最近更新 更多