2016-12-02 2 views
0

<ListView> 구성 요소에서 작업 중입니다. 이름 목록이 있지만 상태를 변경 한 후에는 값이 변경되지만 ListView는 다시 렌더링되지 않습니다.ListView는 react-native에서 상태가 변경된 후에 다시 렌더링하지 않습니까?

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

친절을 통해 이동하시기 바랍니다 내 위 코드를 읽고 알려주세요. f 모든 해결책을 나타냅니다.

감사합니다.

답변

0

문제는 자바 스크립트의 일부이며 ListView입니다. 이 함수는 ListView.DataSource를 생성 할 때 발생합니다.

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

rowHasChanged는 현상이 발생 렌더링하는 경우 제어 무엇이며, 기존의 객체가 새로운 개체와 같은지 있는지 확인합니다.

두 개체를 서로 비교하면 항목 중 하나가 변경된 경우 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을 확인하십시오.