Reputation: 2381
Let's imagine there are 2 React Native components < Parent> and < StarRating>.
< Parent> is container that keeps rating value (from 1 to 5) in its state.
< StarRating> is a component that renders star images according to received prop "rating" OR according to what star is clicked.
< StarRating> looks something like this:
class Parent extends Component {
constructor(props) {
super(props);
this.state = {
rating:5
}
}
render() {
return (
<StarRating rating={this.state.rating}></StarRating>
)
}
}
class StarRating extends Component {
_generateStars(rating) { ... }; //return an array with JSX rect components
//according to "rating" prop (e.g. 1,2..5).
//Each component is the star image...
render() {
stars = this._generateStars(this.props.rating); // *
return (
<View>
{stars}
</View>
)
}
}
In case < StarRating> received new prop "rating" its Render function automatically calls with new prop and everything is ok, we see updated stars images.
Each star wrapped to < TouchableOpacity> element and what should I do if I click to some star and < StarRating> should be re-rendered itself with new count of stars. In this case I can't change "this.props.rating" inside < StarRating> directly (see * above). I think I have to use setState() inside < StarRating> but how < StarRating> can understand which way Render should be... according to new state or to new received prop? I mean how can I determine in Render function is new prop received or click generated?
It is looks like < StarRating> should have 2 way to update its own stars:
through new props from parent.
through click on a star inside itself.
What approach should be in this case?
Thanks.
Upvotes: 0
Views: 3436
Reputation: 266
I guess what you confused is WHO should control the state of rating
(indicate the different star image).
I think parent component should control this state, because the child component (StarRating) is just a view reflect the state of rating
, he does not care what the meaning of this state, who should care the state meaning is his parent (Parent).
Also, control all children rating
states in parent is easy to extend function in the future.
Upvotes: 1
Reputation: 5442
I would let StarRating
manage this state, but your approach is also viable, depending on the situation.
You can pass an updateRating
function through your parent, and then you can control the rating from StarRating without moving the state into it.
class Parent extends Component {
constructor(props) {
super(props);
this.state = {
rating:5
}
}
render() {
return (
<StarRating rating={this.state.rating}
updateRating={(rating) => this.setState({rating})}
/>
)
}
}
class StarRating extends Component {
_generateStars(rating, updateRating) {
// Generate stars with custom onPress
// <Star onPress={() => updateRating(starIndex)} />
}
render() {
stars = this._generateStars(this.props.rating, this.props.updateRating); // *
return (
<View>
{stars}
</View>
)
}
}
Upvotes: 1