2016-12-02 24 views
0

私は<ListView>コンポーネントで作業していますが、名前のリストがありますが、状態を変更した後は値が変更されていますが、ListViewは再描画されません。リストビューは反応ネイティブの状態変更後に再レンダリングしませんか?

isSelect:偽 - (州)

enter image description here

isSelect:真 - (州)

enter image description here

コード:

var designerName = [{id: 'Calvin Klein', name: 'Calvin Klein', isSelected: false}, 
       {id: 'Donatella Versace', name: 'Donatella Versace', isSelected: false}, 
       {id: 'Valentino Garavani', name: 'Valentino Garavani', isSelected: false}, 
       {id: 'Giorgio Armani', name: 'Giorgio Armani', isSelected: false}]; 

export default class filter extends Component { 
    constructor() { 
     super(); 
     const listDs = new ListView.DataSource({ 
      rowHasChanged: (r1, r2) => r1 !== r2, 
     }); 
     this.state = { 
      listDs:designerName 
     }; 
    } 

componentDidMount(){ 
    this.setState({ 
    designerDataSource:this.state.designerDataSource.cloneWithRows(this.state.listDs), 
    }) 
} 

render() { 
    return (
     <View> 
      <ListView 
       dataSource={this.state.designerDataSource} 
       renderRow={this.renderRow.bind(this)} 
      /> 
     </View> 
    ); 
} 

renderRow(item){ 
    return (
     <TouchableHighlight key={item.id} onPress={this.onItemDesigner.bind(this, item)}> 
       <View> 
        <View> 
         {this.renderName(item)} 
        </View> 
        <View> 
         <Text>{item.name}</Text> 
        </View> 
       </View> 
      </TouchableHighlight> 
    ); 
} 

renderName(item){ 
    if(item.isSelected) { 
     return(
      <Image 
       style={{ 
        width: 15, 
        height:15}} 
       source={require('../images/black_tick_mark.png')} /> 
     ); 
    } 
} 

onItemDesigner(item){ 
    var tempDesigner = this.state.listDs.slice(); 

    for(var i=0; i<tempDesigner.length; i++){ 
     if (tempDesigner[i].id == item.id && !tempDesigner[i].isSelected) { 
      tempDesigner[i].isSelected = true; 
     }else if (tempDesigner[i].id == item.id && tempDesigner[i].isSelected){ 
      tempDesigner[i].isSelected = false; 
     } 
    } 
    this.setState({ 
     designerDataSource: this.state.designerDataSource.cloneWithRows(tempDesigner), 
    }); 
    } 
} 

親切に私を通過してください上記のコードを私に教えてください。どんな解決策であれ

答えて

0

問題

おかげで一部のJavascript、パーツリストビューです。この関数は、ListView.DataSourceを構築するときに発生します。

const listDs = new ListView.DataSource({ 
    rowHasChanged: (r1, r2) => r1 !== r2, 
}); 

rowHasChangedは起こるべきレンダリング場合を制御するものであり、古いオブジェクトが新しいオブジェクトに等しいかどうかをチェックです。

2つのオブジェクトを比較すると、アイテムの1つが変更されてもfalseが返されません。実際のオブジェクト自体が別のメモリ位置を指しているかどうかを確認します。

これらの例を検討してください。

let array1 = [{foo: 'bar'}] 
let array2 = array1.slice() 
// sliced array still contains references to the items 
console.log(array2[0] === array1[0]) 
// => true 

// change something in array1 
array1[0].foo = 'test' 
// you'll see the change in array2 as well 
console.log(array2[0].foo) 
// => 'test' 

それは新しい変数の場所を持っているようにするには、空の{}オブジェクトを作成し、元のキーを反復処理し、新しいもの、または、少し楽にキー/値を保存することができますいずれかを使用することですJSON.parse(JSON.stringify(obj))を使用してオブジェクトをクローンします。

array2[0] = JSON.parse(JSON.stringify(array1[0])) 
console.log(array2[0] === array1[0]) 
// => false 

技術的には、アレイ全体をその方法で、または変更したものだけをクローンすることができます。私は不要なレンダリングを防ぐために、変更されたオブジェクト上でのみ行うほうが効率的だと思います。

チェックアウトObject equality in JavaScript

関連する問題