React useState - FaStar 图标 - 点击更改和更改回来

React useState - FaStar icons - Click To Change and Change Back

我正在学习 React JS 并花一些时间在 useState 上。

我有以下代码(也可在此处的沙盒上使用 - https://codesandbox.io/s/starswithclicks-dlhjh

import React from "react";
import { FaStar } from "react-icons/fa";
import { useState } from "react";

const Star = ({ selected = false, StarClicked = (f) => f }) => (
  <FaStar color={selected ? "red" : "grey"} onClick={StarClicked} />
);

function StarRating() {
  const [firstStar, setfirstStar] = useState(false);
  const [secondStar, setSecondStar] = useState(false);
  const [thirdStar, setThirdStar] = useState(false);
  return (
    <div>
      <p>Stars will come here</p>
      <Star
        selected={true}
        StarClicked={() => {
          setfirstStar(true);
          setSecondStar(true);
          setThirdStar(true);
        }}
      />
      <Star
        selected={firstStar}
        StarClicked={() => {
          setfirstStar(true);
          setSecondStar(false);
          setThirdStar(false);
        }}
      />
      <Star
        selected={secondStar}
        StarClicked={() => {
          setfirstStar(false);
          setSecondStar(true);
          setThirdStar(false);
        }}
      />
      <Star
        selected={thirdStar}
        StarClicked={() => {
          setfirstStar(false);
          setSecondStar(false);
          setThirdStar(true);
        }}
      />
      <Star
        selected={false}
        StarClicked={() => {
          setfirstStar(false);
          setSecondStar(false);
          setThirdStar(false);
        }}
      />
    </div>
  );
}

export default StarRating;

现在,我已经设法使用上面的代码完成以下操作,这是我给自己做的一个简单练习。

现在,我想在屏幕上显示一个简单的消息,如果星星(中间三个)已经亮起。例如。

  1. 一开始,中间的三颗星都是灰色的。
  2. 我点击中间那个,它变成了红色。
  3. 我又点了中间那个,下面出现了一个简单的信息,说已经开机了。

本质上,我想检查给定星星的选择 属性 是真还是假,并相应地在底部显示一条简单消息。

如果状态已经设置,您需要添加对父方法的调用(使用道具)以显示点击事件的错误。

查看父级起始索引错误的示例:https://codesandbox.io/s/starswithclicks-forked-4m3j5?file=/src/StarRating.js

家长:

export default function App() {
  const [haseError, setShowError] = useState(false);
  const showError = () => {
    setShowError(true);
  };
  return (
    <div className="App">
      <h1>Basic State Practice</h1>
      <StarRating showError={showError} />
      {haseError ? <div> star already clicked</div> : null}
    </div>
  );
}

还有一个明星范例

 <Star
        selected={secondStar}
        StarClicked={() => {
          if (secondStar) props.showError();
          setfirstStar(false);
          setSecondStar(true);
          setThirdStar(false);
        }}
      />

编辑

您可以在 StarRating 组件中执行相同的操作:https://codesandbox.io/s/starswithclicks-forked-kfnho?file=/src/StarRating.js


function StarRating(props) {
  const [firstStar, setfirstStar] = useState(false);
  const [secondStar, setSecondStar] = useState(false);
  const [thirdStar, setThirdStar] = useState(false);
  const [clickedStar, setShowError] = useState(-1);
  const showError = (index) => {
    setShowError(index);
  };
  return (
    <div>
      <p>Stars will come here</p>
      <Star
        selected={true}
        StarClicked={() => {
          setfirstStar(true);
          setSecondStar(true);
          setThirdStar(true);
        }}
      />
      <Star
        selected={firstStar}
        StarClicked={() => {
          if (firstStar) showError(2);
          setfirstStar(true);
          setSecondStar(false);
          setThirdStar(false);
        }}
      />
      <Star
        selected={secondStar}
        StarClicked={() => {
          if (secondStar) showError(3);
          setfirstStar(false);
          setSecondStar(true);
          setThirdStar(false);
        }}
      />
      <Star
        selected={thirdStar}
        StarClicked={() => {
          if (thirdStar) showError(4);
          setfirstStar(false);
          setSecondStar(false);
          setThirdStar(true);
        }}
      />
      <Star
        selected={false}
        StarClicked={() => {
          setfirstStar(false);
          setSecondStar(false);
          setThirdStar(false);
        }}
      />
      {clickedStar >= 0 ? <div> star {clickedStar} already clicked</div> : null}
    </div>
  );
}