替换状态中存储的对象不会更新视图

时间:2015-11-12 00:27:20

标签: listview reactjs react-native

您可以在下面找到相关的代码和屏幕截图。同样,还有一个working demo at rnplay.org

简而言之,这就是问题所在。我有一个ListView。根据存储在状态中的对象的映射,每行的日期是动态的。当我单击 Cycle Dates 按钮时,我会替换应更新每一行日期的对象this.state.cacheTimestamps。至少那是我期望发生的事情。任何人都可以帮助我理解为什么实际上并没有发生这种情况?

class SampleApp extends React.Component{

  constructor(props){
    super(props);
    this.ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });

    this.state = {
      dataSource: this.ds.cloneWithRows(['ABCD','EFGH','IJKL']),
      cacheTimestamps: {},
      cacheLotery: [
        {'ABCD': 'Jan 1, 1970'},
        {'ABCD': 'Jan 2, 1970', 'EFGH': 'Jan 2, 1971'},
        {'ABCD': 'Jan 3, 1970', 'EFGH': 'Jan 3, 1971', 'IJKL': 'Jan 3, 1972'},
      ],
    }

    // this.randomIntBetween.bind(this);
  }

  componentWillMount(){
     this.setState({
       cacheTimestamps: this.state.cacheLotery[this.randomIntBetween(0,2)]
     })
  }

  row( id ){
    let lastCached = (this.state.cacheTimestamps[id]) ? this.state.cacheTimestamps[id] : 'never';

     return(
        <View>
          <Text style={styles.label}>
            {id}
          </Text>
          <Text style={styles.cache}>
            {lastCached}
          </Text>
        </View>
     )
  }

  cycleDates(){
    const min = 0;
    const max = 2;
    const idx = this.randomIntBetween(min,max);

    this.setState({
      cacheTimestamps: this.state.cacheLotery[ idx ]
    }, ()=> console.log('dbug cycleDates, new index [%i] and cacheTimestamps Object is %O', idx, this.state.cacheTimestamps));
  }

  randomIntBetween(min, max) {
    return Math.floor(Math.random() * (max - min)) + min;
  }

  render() {
    return (
      <View style={styles.container}>
        <ListView
          dataSource={this.state.dataSource}
          renderRow={this.row.bind(this)} 
        />
        <TouchableHighlight
          onPress={ ()=>this.cycleDates() } >
          <Text style={styles.buttonTxt}>
            Cycle Dates
          </Text>
        </TouchableHighlight>
      </View>
    );
  }
};

顺便说一句,考虑到它可能没有将新对象视为不同的对象,我也尝试Object.assign来确保它是一个全新的对象。

  cycleDates(){
    const min = 0;
    const max = 2;
    const idx = this.randomIntBetween(min,max);

    this.setState({
      cacheTimestamps: Object.assign({}, this.state.cacheLotery[ idx ])
    }, ()=> console.log('dbug cycleDates, new index [%i] and cacheTimestamps Object is %O', idx, this.state.cacheTimestamps));
  }

enter image description here

2 个答案:

答案 0 :(得分:0)

您需要在ListView中使用renderRow并将this.state.cacheTimestamps作为道具传递。

render() {
  return (
    <View style={styles.container}>
    <ListView
      dataSource={this.state.dataSource}
      timeStamps={this.state.cacheTimestamps} 
  />
  <TouchableHighlight onPress={ ()=>this.cycleDates() } >
  <Text style={styles.buttonTxt}>
    Cycle Dates
    </Text>
    </TouchableHighlight>
    </View>
 );
}

答案 1 :(得分:0)

解决了!

更新setState时,我还需要更新dataSource。 Working Demo at RNPlay也已更新。

{{1}}