2016-12-02 2 views
0

Я работаю над компонентом <ListView>, у меня есть список имен, но после изменения состояния он меняет значения, но не перерисовывает ListView.ListView не перезаписывает после изменения состояния в реакции-native?

isSelect: ложь - (State)

enter image description here

isSelect: истинный - (State)

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

Просьба пройти через мой выше кода и дайте мне знать, если вы ind любое решение.

Благодаря

ответ

0

выпуска является частью Javascript, часть 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.

Смежные вопросы