Stich
Stich

Reputation: 2381

How to update state according to received props in runtime in React Native?

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: enter image description here

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:

  1. through new props from parent.

  2. through click on a star inside itself.

What approach should be in this case?

Thanks.

Upvotes: 0

Views: 3436

Answers (2)

yifan_z
yifan_z

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

Moti Azu
Moti Azu

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

Related Questions