【问题标题】:Replacing Object Stored in State does not Update View替换存储在状态中的对象不会更新视图
【发布时间】:2015-11-12 00:27:19
【问题描述】:

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

简而言之,这就是问题所在。我有一个列表视图。每行的日期都是动态的,基于对存储在 state 中的对象的映射。当我单击 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));
  }

【问题讨论】:

    标签: listview reactjs react-native


    【解决方案1】:

    你需要在 ListView 中渲染 Row 并将 this.state.cacheTimestamps 作为 prop 传递。

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

    【讨论】:

    • Stephens - 感谢您的回复,但我不明白您的建议。在您的示例中,您删除了我认为是错误的 renderRow 函数,但随后添加 timeStamps 大概是为了将 this.props.timeStamps 变量传递到 renderRow 函数中,但是当我在 renderRow 函数中 console.log(this.props) 时,它返回一个对象值为{rootTag: 1}。您能否分叉 rnplay 链接并提供一个工作示例来展示您的建议?
    • 嗯,你说它不是 React-Native 特有的,但 ListView 是 React-Native 特有的。我将它视为 ListView 是您可以编辑的组件之一,并将 renderRow 放在那里。我还没有尝试过 React-Native。
    • 啊,好吧……对不起。关于它是一个通用的反应问题,我可能错了。我认为无论如何在反应中传递一个对象都是一样的。感谢您的宝贵时间。
    • 顺便说一句,我认为问题在于状态更新会影响渲染。 IE。你的 row(id) 方法不会知道状态变化。
    • 我刚刚找到并发布了解决方案,即更新数据源以及对象引用。再次感谢!
    【解决方案2】:

    已解决!

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

      cycleDates(){
        const min = 0;
        const max = 3;
        const idx = this.randomIntBetween(min,max);
    
        this.setState({
          cacheTimestamps: this.state.cacheLotery[ idx ],
          dataSource: this.ds.cloneWithRows(['ABCD','EFGH','IJKL']),
        }, ()=> console.log('dbug cycleDates, new index [%i] and cacheTimestamps Object is %O', idx, this.state.cacheTimestamps));
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-12
      相关资源
      最近更新 更多