Reputation: 17
I'm attempting to write a function to remove a React Native component (named "Card") from the DOM on-click, then append a new "Card" of the same class with different properties. For example, both Cards have background colors. If the first Card is green, the second Card, which should have a blue background, will inherit the green background of the original Card.
The Cards receive their background color passed as props, like so:
class Card extends Component {
constructor(props) {
super(props);
this.state = {
style: {
backgroundColor: this.props.card.backgroundColor
}
};
}
render() {
return (
<TouchableHighlight style={this.state.style}>
<Image source={this.props.card.img} />
</TouchableHighlight>
)
}
}
The main component looks like this:
class SetProject extends Component {
constructor(props) {
super(props);
this.state = {
cardArray: [{backgroundColor: 'green', img: require('~/SetProject/cardImages/ovals/1-red-empty-oval.png')}]
}
}
removeCard(){
let emptyArray = [];
this.setState({cardArray: emptyArray});
}
changeCard(){
// let emptyArray = [];
// this.setState({cardArray: emptyArray});
let newCardArray = [{backgroundColor: 'red', img: require('~/SetProject/cardImages/ovals/1-purple-shaded-oval.png')}]
this.setState({cardArray: newCardArray});
}
render() {
let cardElementArray = this.state.cardArray.map(theCard => {
return (
<Card card={theCard}></Card>
);
});
return (
<View>
<View>
{cardElementArray}
</View>
<TouchableHighlight>
<Text onPress={this.removeCard.bind(this)}>Remove Card</Text>
</TouchableHighlight>
<TouchableHighlight>
<Text onPress={this.changeCard.bind(this)}>Change Background</Text>
</TouchableHighlight>
</View>
);
}
}
So I've got two buttons: removeCard, which works great, and changeCard. If I press "Remove Card" and then press "Change Card," I see the exact results I'm looking for. The card is removed and is replaced by a new one. However, if I comment in these lines in changeCard:
// let emptyArray = [];
// this.setState({cardArray: emptyArray});
and press "Change Card" without pressing "Remove Card," the new Card has a new image but it keeps the background color of the previous Card. This also happens if I call this.removeCard() from changeCard.
In summary, I'd like to be able to perform the behavior of both of these functions simultaneously, but I'm only able to remove a Card and add a new, correctly rendered Card if I press both buttons separately.
Any ideas would be much appreciated!
Upvotes: 0
Views: 160
Reputation: 903
Don't you get warning about missing keys in array? Use unique identifier (or it's index in array as last resort) for each card, and use it to set key
prop on each item in array. This way, when card in array changes, react can re-render it, because it's a new card to it.
let cardElementArray = this.state.cardArray.map(theCard => {
return (
<Card key={theCard.id} card={theCard}></Card>
);
});
Read more about keys here in React docs.
Upvotes: 0
Reputation: 1690
Here you're using props for setting image but not setting style. You can use props as well. You have set the style in constructor. Then you want to change style but constructor is not called again but creating a new object. You can use props setting styl as well
render() {
return (
<TouchableHighlight style={this.props.card.style}>
<Image source={this.props.card.img} />
</TouchableHighlight>
)
}
For better implementation in case properties of card gets more complex add an id property to card. You can use componentWillReceiveprops by this way unnecessary renders are neglected as well.
[{id:'1', backgroundColor: 'red', img: require('~/SetProject/cardImages/ovals/1-purple-shaded-oval.png')}]
class Card extends Component {
constructor(props) {
super(props);
this.state = {
style: {
card: this.props.card
}
};
}
componentWillReceiveProps(nextProps){
if(nextProps.card.id != this.state.card.id)
{
setState({card:nextProps.card})
}
}
render() {
return (
<TouchableHighlight style={this.state.style}>
<Image source={this.props.card.img} />
</TouchableHighlight>
)
}
}
https://facebook.github.io/react/docs/react-component.html#componentwillreceiveprops
Upvotes: 1