Reputation: 81
I am new to react and have started following through the book learning react by Alex Banks and Eve Porcello. I have got to a section that creates a star rating system but at the moment I cant get it working can anyone tell me why? As far as I can tell I have copied the code correctly and everything looks like it should work as intended. Here is the code I have:
const Star = ({ selected=false, onClick=f=>f }) =>
<div className={ (selected) ? "star selected" : "star" } onClick={onClick}>
</div>
Star.propTypes = {
selected: PropTypes.bool,
onClick: PropTypes.func
}
class StarRating extends React.Component {
constructor(props) {
super(props)
this.state = { starsSelected: 0 }
this.change = this.change.bind(this)
}
change(starsSelected) {
this.setState({ starsSelected: starsSelected })
}
render() {
const { totalStars } = this.props
const { starsSelected } = this.state
return(
<div className="star-rating">
{[...Array(totalStars)].map((n,i) =>
<Star
key={i}
selected={i<starsSelected}
onClick={() => this.change(i+1)}
/>
)}
<p>{starsSelected} of {totalStars} stars</p>
</div>
)
}
}
StarRating.propTypes = {
totalStars: PropTypes.number
}
StarRating.defaultProps = {
totalStars: 5
}
When inspecting the components in react-dev-tools it seems that the stars selected prop is always set to false and I cant figure out why. Thanks for any help anyone can offer
Upvotes: 1
Views: 6100
Reputation: 811
import { FaStar } from "react-icons/fa";
const CreateArray = (length) => [...Array(length)]; // This will create Array with the length provided.
// Star Component
function Star({ selected = false, onSelect }) {
return (
<FaStar color={selected ? "orange" : "lightgray"} onClick={onSelect} />
);
}
// Star Rating component
function StarRating({ totalStars = 5 }) {
const [selectedStars, setSelectedStars] = useState(0);
return (
<>
{CreateArray(totalStars).map((n, i) => (
<Star
key={i}
selected={selectedStars > i}
onSelect={() => setSelectedStars(i + 1)}
/>
))}
<p>
{selectedStars} of {totalStars} // To display selected stars out of total stars
</p>
</>
);
}
function App() {
return <StarRating totalStars={5} />; // This will display 5 stars
}
Working example - Star Rating - CodeSandbox
Upvotes: 0
Reputation: 911
Inject : npm i star-based-rating
directly.
For Reference on this react package: star-based-rating
Upvotes: 0
Reputation: 169
Your code is working absolutely fine. Check out this link : https://codesandbox.io/s/01wqmzrpjl
Make sure while declaring css classes star is above selected else it will not show the selected style fields if it has same style-field in star className.
Example in my link if I declare selected class above star class then red background (selected style property) is override by grey background (star style property).
Upvotes: -1
Reputation: 1095
The code shared is perfectly fine. Just render something from this code on which the click event would be fired.
const Star = ({ selected=false, onClick=f=>f }) =>
<div className={ (selected) ? "star selected" : "star" } onClick={onClick}>
// Something to render maybe?
</div>
Upvotes: 1
Reputation: 799
It can be 2 things:
this line: {[...Array(totalStars)].map((n,i) =>
You need to pass totalStars
as a Number and not a string:
<StarRating totalStars={5} />
or
you are not display anything in your Star component. Try this:
const Star = ({ selected = false, onClick = f => f }) => (
<div className={selected ? "star selected" : "star"} onClick={onClick}>
Star
</div>
);
See a working example:
https://codesandbox.io/s/52ox6wmwwk
Upvotes: 1