React 星级评定

React star rating

提问人:raul atofanei 提问时间:5/22/2023 最后编辑:raul atofanei 更新时间:5/22/2023 访问量:206

问:

我有一个食谱应用程序,我实施了星级评定,我必须将值保存在本地存储中并显示平均评定值。我在阅读答案后更新了代码,以便在本地存储中获取配方 ID 和评级,它有点工作。使用控制台日志,我能够看到评级和 id 显示良好,但本地存储中没有保存任何内容,我不明白为什么有任何帮助?

代码如下:

import styled from "styled-components";
import Searched from "../Pages/Searched";
import { useParams } from "react-router-dom";
const StarRating = () => {
  

  let params = useParams();
  const [details, setDetails] = useState({});
  const [activeTab, setActiveTab] = useState("instructions");
  
  const fetchDetails = async () => {
      const data = await fetch(
      `https://api.spoonacular.com/recipes/${params.name}/information?apiKey=${process.env.REACT_APP_API_KEY}`
      );
      const detailData = await data.json();
      setDetails(detailData);
      console.log(detailData);
  };

  useEffect(() => {
      fetchDetails();
  }, [params.name]);

    const [rating, setRating] = useState(0);
    const [hover, setHover] = useState(0);

    useCallback(() => {
      const data = localStorage.getItem("rating");
      if (data) {
        data[details.id] = rating;
        localStorage.setItem("rating", JSON.stringify(data));
      } else {
        localStorage.setItem("rating", JSON.stringify({ [details.id]: rating }));
      }
    }, [rating]);
    
    
    return (
        <StarStyle>
      <div className="star-rating">
        {[...Array(5)].map((star, index) => {
          index += 1;
          return (
            <button
              type="button"
              key={index}
              className={index <= (hover || rating) ? "on" : "off"}
              onClick={() => setRating(index)}
              onMouseEnter={() => setHover(index)}
              onMouseLeave={() => setHover(rating)}
            >
              <span className="star">&#9733;</span>
            </button>
          );
        })}
      </div>
      </StarStyle>
    );
  };


export default StarRating;

const StarStyle = styled.form`
button {
    background-color: transparent;
    border: none;
    outline: none;
    cursor: pointer;
    block-size: 150px;
    font-size: 60px;
  }
  .on {
    color: #000;
  }
  .off {
    color: #ccc;
  }
`;

ReactJS 评级

评论


答:

0赞 Ahmad Alfy 5/22/2023 #1

您可以使用一个钩子来监视 的变化,并将其设置在 .useEffectratinglocalStorage

例如,您需要执行如下操作:

import React, { useState, useCallback } from "react";
import styled from "styled-components";

  const StarRating = () => {
  const [rating, setRating] = useState(0);
  const [hover, setHover] = useState(0);

  useCallback(() => {
    localStorage.setItem("rating", JSON.stringify(rating));
  }, [rating]);

  return (
    <StarStyle>
      <div className="star-rating">
        {[...Array(5)].map((star, index) => {
          index += 1;
          return (
            <button
              type="button"
              key={index}
              className={index <= (hover || rating) ? "on" : "off"}
              onClick={() => setRating(index)}
              onMouseEnter={() => setHover(index)}
              onMouseLeave={() => setHover(rating)}
            >
              <span className="star">&#9733;</span>
            </button>
          );
        })}
      </div>
  </StarStyle>
  );
};

export default StarRating;

这是一个简单的实现,它将评级的值设置为每当状态更改时。localStoragerating

在现实生活中,您需要将产品 ID 与评级一起保存,因此如果您有多个产品,您可以显示正确的评级。我建议您将 作为 prob 传递给组件,然后在 localStorage 中设置一个具有所有评级的对象,其中使用产品 ID 作为键。productId

那是这样的:

  const StarRating = (productId) => {

  ...

  useCallback(() => {
    const data = localStorage.getItem("rating");
    if (data) {
      data[productId] = rating;
      localStorage.setItem("rating", JSON.stringify(data));
    } else {
      localStorage.setItem("rating", JSON.stringify({ [productId]: rating }));
    }
  }, [rating]);

...

正如你所看到的,我们将产品 ID 作为 prob 传递给组件,然后在钩子中寻找本地存储中以前存储的数据。

如果存在,我们会更新数据。如果没有,我们将创建一个存储数据的新对象。

评论

0赞 raul atofanei 5/22/2023
感谢您的回复,这非常有帮助,我也在想我必须获得带有产品 ID 的评级,以避免每个食谱都获得相同的评级,如果它不会太多,我可以要求关于如何做到这一点的提示吗?
0赞 raul atofanei 5/22/2023
谢谢!我用我所做的事情更新了ocde,现在的问题是我没有在本地存储中保存任何东西,我不明白为什么
0赞 Muhammad Awais 5/22/2023 #2

首先在 React js 中为 Rating 制作一个组件 并遵循以下代码:

import React, { useState } from "react";
import "./StarRating.css";

const StarRating = () => {



const [rating, setRating] = useState(0);
  const [hover, setHover] = useState(0);
  return (
    <div className="star-rating">
      {[...Array(5)].map((star, index) => {
        index += 1;
        return (
          <button
            type="button"
            key={index}
            className={index <= (hover || rating) ? "on" : "off"}
            onClick={() => setRating(index)}
            onMouseEnter={() => setHover(index)}
            onMouseLeave={() => setHover(rating)}
          >
            <span className="star fs-2">&#9733;</span>
          </button>
        );
      })}
    </div>
  );
};

export default StarRating;

并制作CSS文件并编写此代码

button {
  background-color: transparent;
  border: none;
  outline: none;
  cursor: pointer;
}
.on {
  color: #ffd900;
}
.off {
  color: #ffd90073;
}

并在任何地方使用它