React Native ListView 不会通过单击重新呈现状态更改

Posted

技术标签:

【中文标题】React Native ListView 不会通过单击重新呈现状态更改【英文标题】:React Native ListView not re-rendering on state change by click 【发布时间】:2016-11-09 18:01:24 【问题描述】:

这是我的示例代码,我希望在点击时更新 ListView 元素。

这一行定义了样式:

(this.state.selectedField.id==field.id)?'green':'white'

在此示例中,活动的View 应以绿色突出显示。 handleClick() 内部的状态正在更新,但没有调用 renderField() 方法。

如何让ListView在点击触发状态改变时重新渲染?

RNPlayNative Link

import React, Component from 'react';
import 
  AppRegistry,
  View,
  ListView,
  Text,
  TouchableOpacity
 from 'react-native';

class SampleApp extends Component 

  constructor(props) 
    super(props);
    var ds = new ListView.DataSource(
        rowHasChanged: (row1, row2) => row1 !== row2,
    );
    this.state = 
      fields: ds.cloneWithRows([
        id:0,id:1,id:2
      ]),
      selectedField: id:0
    ;
  

  handleClick(field) 
    console.log("Selected field:",field);
    this.setState(
      selectedField: field
    );
  

  renderField(field) 
    return (
      <TouchableOpacity onPress=this.handleClick.bind(this, field) >
        <View style=backgroundColor:(this.state.selectedField.id==field.id)?'green':'white'>
          <Text style=left:0, right:0, paddingVertical:50,borderWidth:1>field.id</Text>
        </View>
      </TouchableOpacity>
    );
  

  render() 
    return (
      <View>
        <ListView
          dataSource=this.state.fields
          renderRow=this.renderField.bind(this)
        />
      </View>
    );
  


AppRegistry.registerComponent('SampleApp', () => SampleApp);

【问题讨论】:

试试这个:***.com/questions/26882177/… 我已经在使用内联样式了,问题在于动态链接样式到点击等事件的状态。 【参考方案1】:

已经回答过很多次了,如果你想改变一个props上的行渲染,如果你想行更新,这个props需要进入你的数据。

查看以下 2 个答案:

https://***.com/a/38001185/343892

https://***.com/a/34718220/343892

【讨论】:

【参考方案2】:

这是我对问题的解决方案,但处理每次点击仍然需要很长时间:

handleClick(field) 
  newFields = this.state.fields.map( (x) => x.key === field.key && x.active !== true ? ...x,active:true : ...x,active:false)  
  this.setState(
    fields:newFields,
    dataSource: this.state.dataSource.cloneWithRows(newFields)
  );

【讨论】:

【参考方案3】:

当数据源更改时,列表会再次呈现,在您的示例中,由于数据源永远不会改变,因此列表视图永远不会重新呈现。这可以通过在状态变量中添加一个字段来保存 dataSource 的数据来实现。在 componentDidMount 方法中,让 dataSource 克隆具有数据状态变量的行。每当您想重新渲染列表视图时,您只需更改数据状态变量,列表将自动重新渲染。我已经更改了您的数据,以便为每个对象添加一个选定状态。这是更新后的代码。

class SampleApp extends Component 

  constructor(props) 
     super(props);
     var ds = new ListView.DataSource(
         rowHasChanged: (row1, row2) => row1 !== row2,
    );
     var dataVar = [
         
           id:0,
           selected: true,
         ,
           id:1,
           selected: false,
         ,
           id:2,
           selected: false,
         
       ];
     this.state = 
       data: dataVar,
       fields: ds,
     ;
   

   componentDidMount() 

     this.setState(
       fields: this.state.fields.cloneWithRows(dataVar)
     );
   


   handleClick(field) 
     console.log(field);
     field.selected = !field.selected;

     var dataClone = this.state.data;
     console.log(dataClone);

     dataClone[field.id] = field;

     this.setState(
       data: dataClone,
     );
   

   renderField(field) 
     let color = (field.selected == true)?'green':'white';
     return (
       <TouchableOpacity onPress=this.handleClick.bind(this, field) >
         <View style=backgroundColor:color>
           <Text style=left:0, right:0, paddingVertical:50,borderWidth:1>     field.id</Text>
         </View>
       </TouchableOpacity>
     );
   

   render() 
     return (
       <View>
         <ListView
           dataSource=this.state.fields
           renderRow=(field) => this.renderField(field)
         />
       </View>
     );
   
 

这是一个有效的 rnplay sample

【讨论】:

你忘了在componentDidMount中修复这条线:fields: this.state.fields.cloneWithRows(this.state.data) 我尝试了解决方案,但由于某种原因,我无法在更新data 时触发renderField() 功能。 handleClick() 工作正常,data 得到更新。 好的,到目前为止,我已经成功了。我的应用程序有这行:if (!this.state.loaded) return this.renderLoadingView(); 用于推迟视图渲染,直到加载数据,由于某种原因阻止了 renderField() 调用。

以上是关于React Native ListView 不会通过单击重新呈现状态更改的主要内容,如果未能解决你的问题,请参考以下文章

React Native ListView数据展示

React Native的ListView的布局使用

React-Native之ListView的3种样式

react-native ListView - 我只需要渲染 DataSource 中的一些对象

React-native ListView DataSource 未更新

React Native:如何在 ScrollView/ListView 子项进入/离开视口时为其设置不透明度动画?