2015-10-30 35 views
10

Nie jestem pewien, dlaczego ListView nie aktualizuje się, gdy moje dane się zmieniają. Mam paski mój kod w dół, aby to łatwe do odczytania i stworzył rnplay:React Native ListView nie aktualizuje po zmianie danych

https://rnplay.org/apps/ivG0mg

Czego spodziewać się zdarzyć to, że użytkownik kliknie element listy a wiersz jest bool isCollapsed jest przełączana podejmowania tło czerwony. Co się dzieje, to źródło danych jest aktualizowane, ale widok listy nie rozpoznaje zmiany i nic nowego nie jest renderowane. Jakieś pomysły?

'use strict'; 

var React = require('react-native'); 

var { 
    ScrollView, 
    Text, 
    Image, 
    StyleSheet, 
    TouchableHighlight, 
    AppRegistry, 
    View, 
    ListView, 
} = React; 

var styles = StyleSheet.create({ 
    container: { 
     flex: 1, 
     flexDirection: 'column', 
     padding: 15, 
    }, 
    red: { 
     backgroundColor: "red", 
    } 
}); 

var foods = [ 
    {key: 'Almond Milk (Homemade)', details:''}, 
    {key: 'Club Soda', details:'', isCollapsed: true}, 
    {key: 'Coconut Milk/Cream', details:''}, 
    {key: 'Coconut Water', details:''}, 
    {key: 'Coffee/Espresso', details:'', isCollapsed: true}, 
    {key: 'Fruit Juice', details:''}, 
    {key: 'Kombucha', details:''}, 
    {key: 'Mineral Water', details:''}, 
    {key: 'Unsweetened Tea', details:''}, 
    {key: 'Water', details:''}, 
    {key: 'Fruit Juice', details:''}, 
    {key: 'Kombucha', details:''}, 
    {key: 'Mineral Water', details:''}, 
    {key: 'Unsweetened Tea', details:''}, 
    {key: 'Water', details:''}, 
    {key: 'Fruit Juice', details:''}, 
    {key: 'Kombucha', details:''}, 
    {key: 'Mineral Water', details:''}, 
    {key: 'Unsweetened Tea', details:''}, 
    {key: 'Water', details:''}, 
    {key: 'Fruit Juice', details:''}, 
    {key: 'Kombucha', details:''}, 
    {key: 'Mineral Water', details:''}, 
    {key: 'Unsweetened Tea', details:''}, 
    {key: 'Water', details:''}, 
    {key: 'Fruit Juice', details:''}, 
    {key: 'Kombucha', details:''}, 
    {key: 'Mineral Water', details:''}, 
    {key: 'Unsweetened Tea', details:''}, 
    {key: 'Water', details:''}, 
]; 

class SampleApp extends React.Component{ 
    constructor(props){ 
     super(props); 
     var ds = new ListView.DataSource({ 
      rowHasChanged: (row1, row2) => row1 !== row2, 
     }); 
     this.state = { 
      dataSource: ds.cloneWithRows(foods), 
     }; 
    } 
    _renderRow(data, sectionID, rowID) { 
       return (
         <TouchableHighlight 
          style={[ 
            styles.container, 
            data.isCollapsed && styles.red]} 
       onPress={()=>this.onCollapse(rowID)}> 
       <Text>{data.key}</Text> 
      </TouchableHighlight> 
     ); 
    } 
    onCollapse(rowID: number) { 
     console.log("rowID", rowID); 
     foods[rowID].isCollapsed = !foods[rowID].isCollapsed; 
     this.setState({dataSource: this.state.dataSource.cloneWithRows(foods)}); 
    } 
    render() { 
     return(
      <ListView 
       style={styles.subContainer} 
       dataSource={this.state.dataSource} 
       renderRow={this._renderRow.bind(this)} 
       initialListSize={15}/> 
     ) 
    } 
}; 

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

Odpowiedz

11

Oto link do wersji roboczej:

https://rnplay.org/apps/GWoFWg

Są to zmiany muszę zrobić, aby je naprawić:

constructor(props){ 
    super(props); 
    var ds = new ListView.DataSource({ 
     rowHasChanged: (row1, row2) => row1 !== row2, 
    }); 
    this.state = { 
     dataSource: ds.cloneWithRows(foods), 
     db: foods, 
    }; 
} 

i tak:

onCollapse(rowID: number) { 
    var newArray = this.state.db.slice(); 
    newArray[rowID] = { 
     key: newArray[rowID].key, 
     details: newArray[rowID].details, 
     isCollapsed: newArray[rowID].isCollapsed == false ? true : false, 
    }; 
    this.setState({ 
     dataSource: this.state.dataSource.cloneWithRows(newArray), 
     db: newArray, 
    }); 
} 
+0

Link już nie działa ... czy mógłbyś go zaktualizować? Dzięki – chemitaxis

+0

używając '... newArray [rowID]' z es6 możesz ponownie użyć wszystkich kluczy w 'newArray [rowID]' obj .. i po prostu dodaj zmieniony klucz na końcu – jose920405

2

wyglądało to byłoby rozwiązanie trzeba React-Native Updating List View DataSource

Ale grałem się z nim trochę i też nie mógł dostać pracy. https://rnplay.org/apps/sk_ukQ

Nie wiem, czy to pomoże, ale próbowałem to ustawienie tablicy jako puste i jestem w stanie usunąć całą listę ... this.setState ({DataSource: this.state.dataSource.cloneWithRows ([ ])});

Myślę, że z jakiegoś powodu używa on buforowanej wersji oryginalnej tablicy, a nie zaktualizowanej tablicy. Tylko nie wiem, dlaczego.

+0

Dzięki dla linku. Odpowiedź była w komentarzach. Musiałem go odbudować po wprowadzeniu w nim zmiany. Wygląda jak błąd, który mam nadzieję zostanie naprawiony w pewnym momencie. https://rnplay.org/apps/GWoFWg –

+1

Ach, dobrze! Cieszę się, że mogłem przynajmniej wskazać ci właściwy kierunek. Dziękuję za udostępnienie rozwiązania. –

+1

Możesz również pomóc temu facetowi ... http://stackoverflow.com/questions/33436902/how-force-redraw-listview-when-this-state-changed-but-not-the-datasource –

Powiązane problemy