提问人:raul atofanei 提问时间:5/22/2023 最后编辑:raul atofanei 更新时间:5/22/2023 访问量:206
React 星级评定
React star rating
问:
我有一个食谱应用程序,我实施了星级评定,我必须将值保存在本地存储中并显示平均评定值。我在阅读答案后更新了代码,以便在本地存储中获取配方 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">★</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;
}
`;
答:
0赞
Ahmad Alfy
5/22/2023
#1
您可以使用一个钩子来监视 的变化,并将其设置在 .useEffect
rating
localStorage
例如,您需要执行如下操作:
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">★</span>
</button>
);
})}
</div>
</StarStyle>
);
};
export default StarRating;
这是一个简单的实现,它将评级的值设置为每当状态更改时。localStorage
rating
在现实生活中,您需要将产品 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">★</span>
</button>
);
})}
</div>
);
};
export default StarRating;
并制作CSS文件并编写此代码
button {
background-color: transparent;
border: none;
outline: none;
cursor: pointer;
}
.on {
color: #ffd900;
}
.off {
color: #ffd90073;
}
并在任何地方使用它
评论