附加的React Native组件不重新渲染

时间:2016-11-26 04:07:47

标签: reactjs react-native

我正在尝试编写一个函数来从DOM中单击删除React Native组件(名为“Card”),然后添加具有不同属性的同一类的新“Card”。例如,两张卡都有背景颜色。如果第一张卡是绿色,则第二张卡应该具有蓝色背景,将继承原始卡的绿色背景。

卡片会将其背景颜色作为道具传递,如下所示:

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>
  )
 }
}

主要组件如下所示:

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>
    );
  }
}

所以我有两个按钮:removeCard,效果很好,还有changeCard。如果我按“删除卡”然后按“更换卡”,我会看到我正在寻找的确切结果。该卡被移除并被新卡取代。但是,如果我在changeCard中注释这些行:

// let emptyArray = [];
// this.setState({cardArray: emptyArray});

并按“更换卡片”而不按“删除卡片”,新卡片有一个新图像,但它保留了前一张卡片的背景颜色。如果我从changeCard调用this.removeCard(),也会发生这种情况。

总之,我希望能够同时执行这两个功能的行为,但是如果我单独按下两个按钮,我只能删除一张卡并添加一张新的,正确呈现的卡。

任何想法都会非常感激!

2 个答案:

答案 0 :(得分:1)

在这里,您使用道具设置图像但不设置样式。你也可以使用道具。您已在构造函数中设置样式。然后,您想要更改样式,但不会再次调用构造函数,而是创建新对象。 您也可以使用道具设置样式

   render() {
      return (
        <TouchableHighlight style={this.props.card.style}>
          <Image source={this.props.card.img} />
        </TouchableHighlight>
      )
     }

为了更好地实现卡的属性变得更复杂,请向卡添加id属性。您可以通过这种方式使用componentWillReceiveprops,也可以忽略不必要的渲染。

  

[{id:&#39; 1&#39;,backgroundColor:&#39; red&#39;,img:   要求(&#39;〜/ SetProject / cardImages /椭圆形/ 1-紫色阴影-oval.png&#39;)}]

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

答案 1 :(得分:0)

请不要收到关于数组中缺少键的警告?对每张卡使用唯一标识符(或数组中的索引作为最后的手段),并使用它为数组中的每个项目设置key prop。这样,当数组中的卡片发生变化时,反应可以重新渲染它,因为它是一张新卡片。

let cardElementArray = this.state.cardArray.map(theCard => {
  return (
    <Card key={theCard.id} card={theCard}></Card>
  );
});

在React docs中阅读有关密钥here的更多信息。