【问题标题】:Targeting only the clicked item on a mapped component ( React quiz trivia App)仅针对映射组件上的单击项目(React quiz trivia App)
【发布时间】:2020-06-07 08:50:43
【问题描述】:

我正在尝试使用 Open trivia Api 开发一个带有 React 的应用程序。我已经映射了一个按钮组件(使用材料 ui)来显示每个问题的不同答案。我现在正在努力仅针对单击的对象来应用 css 属性:如果答案正确,则应变为绿色,否则为红色。问题是一旦我点击,所有按钮都会变成红色或绿色。我试图将索引存储在一个状态并比较真实的索引,但它不起作用。这是我的代码: 在主APP.js中

  const [clickedOne, setClickedOne] = useState({
    clickedIndex: null,
  });

  useEffect(() => {
    grabData();
  }, []);

  const handleClick = (choice, ke) => {
    setChoice(choice);

    if (choice === data.correct_answer) {
      setIsCorrect(true);
    } else {
      setIsCorrect(false);
    }
    setClickedOne({ clickedIndex: ke });

    grabData();
  };

渲染内的映射按钮:

      {answers.map((answer, index) => {
          return (
            <ContainedButtons
              choice={handleClick}
              answer={answer}
              correct={data.correct_answer}
              isCorrect={isCorrect}
              key={index}
              id={index}
              clicked={clickedOne}
            />
          );
        })}

Button 组件内部:

const backStyle = () => {
    if (clicked === id) {
      if (isCorrect) {
        return "green";
      } else if (isCorrect === false) {
        return "red";
      } else {
        return null;
      }
    }
  };

  return (
    <div className={classes.root}>
      <Button
        style={{ backgroundColor: backStyle() }}
        value={answer}
        onClick={() => choice(answer, id)}
        variant="contained"
      >
        {decodeURIComponent(answer)}
      </Button>

当我现在在 backstyle 函数中检查 clicked===id 时,现在什么也没有发生。如果没有检查,我会将所有按钮都设置为红色或绿色。 谢谢大家的帮助!

【问题讨论】:

  • React 在您执行任何操作(例如单击/检查等)时为您提供 SyntheticEvent 对象。在这种情况下,您将获得 currentTarget。那么,当您可以直接获取 currentTarget 并仅检查该答案是否正确时,为什么要与 index 进行比较,您可以将样式应用于该按钮。希望有帮助!!
  • 我认为 react 不喜欢使用 Event 属性,这就是为什么我将点击的答案作为参数传递。
  • 没有。 React 喜欢玩事件,我的意思是这就是为什么他们创建了一个 Synthetic Event 包装器来为我们提供信息。如果您使用事件,没有编译器会抱怨。你会更容易获得目标并重新绘制它。你可以在 React 文档中阅读更多关于合成事件的信息。干杯!!
  • 谢谢!所以我可以比较 if(clicked=e.target.id)?
  • 正是@Robozombie。支持答案,以便将来对其他人有所帮助。谢谢

标签: javascript reactjs


【解决方案1】:

我看过你的代码框演示,除了你的问题之外,还有很多其他问题。

首先,每次您向 API 发出请求以获取下一个问题时,您都会发出 10 个问题而不是 1 个问题的请求。API 请求 URL 包含一个名为 amount 的查询参数,它决定了多少个问题将在每个请求上获取。将其值更改为 1。

"https://opentdb.com/api.php?amount=1&encode=url3986"

其次,有很多不必要的代码和useState钩子的不必要使用。您只需要在状态中存储 2 个东西,dataanswers

const [data, setData] = useState({});
const [answers, setAnswers] = useState([]);

现在,来解决检测单击了哪个按钮并正确更新其背景颜色的原始问题。

要实现所需的功能,请执行以下步骤:

  1. 创建几个 CSS 类,如下所示

    button.bgGreen {
      background-color: green !important;
    }
    
    button.bgRed {
      background-color: red  !important;
    }
    
  2. handleClick 函数从App 组件传递给ContainedButtons 组件。单击按钮时,将调用此单击处理程序。在 handleClick 函数中,使用 Event.target 获取文本和单击的按钮,并根据用户是否正确回答,在单击的按钮上添加在步骤 1 中创建的适当 CSS 类。

  3. 不要在 map 函数中使用 index 作为 ContainedButtons 的键,而是使用每次都唯一的东西。这是必需的,因为我们希望 React 不重用 ContainedButtons,因为如果 React 重用 ContainedButtons 组件,那么在步骤 2 中添加的 CSS 类将不会从按钮中删除。

这是您的应用的工作codesanbox demo,上面提到的步骤。

在此演示中,我删除了不必要的代码,并将ContainedButtons 内部的key 更改为map 函数key={answer.length * Math.random() * 100}。您可以将其更改为任何可以确保此密钥每次都是唯一的。

【讨论】:

猜你喜欢
  • 2021-12-22
  • 2020-10-27
  • 2021-06-03
  • 2018-06-13
  • 2018-02-19
  • 2022-11-24
  • 2019-05-06
  • 2018-09-04
  • 1970-01-01
相关资源
最近更新 更多