2017-03-04 117 views
1

嘿,所有人都會喜歡這個問題的一些幫助..我一直在撕掉我的頭髮!React-Native ListView與Object Array

我嘗試使用以下格式的對象數組來呈現一個ListView:我使用的成分反應母語碰擦列表視圖發現這裏

Array[number] 
0: Object 
    category: '' 
    date: '' 
    total: '' 
    vendor: '' 
1: Object ..etc. 

swipeList github

但我只渲染了我的數組對象的最後一個元素!我也在這個反應原生應用程序中使用了redux,儘管我沒有看到這個效果。 幫助! :)

輸出如下 enter image description here

這裏是我當前的代碼。

import React, { 
    Component, 
} from 'react'; 
import { 
    ListView, 
    Text, 
    TouchableOpacity, 
    TouchableHighlight, 
    View, 
    Alert 
} from 'react-native'; 
import { connect } from 'react-redux'; 
import { Actions } from 'react-native-router-flux'; 
import { SwipeListView } from 'react-native-swipe-list-view'; 
import { 
    PRIMARY_HIGHLIGHT_COLOUR, 
    CARD_BACKGROUND_COLOUR, 
    BORDER_COLOUR 
} from '../global/colours'; 
import { 
    MySearchBar, 
    Button, 
    FAB, 
    BackgroundView, 
} from '../components'; 
import { HEADER } from '../global/margins'; 

class ReceiptsListView extends Component { 

    constructor(props) { 
     super(props); 
     console.log(this.props.receiptList); 
     this.ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 }); 
     this.state = { 
      listViewData: this.ds.cloneWithRows(this.props.receiptList) 
     }; 
     console.log('state', this.state); 
    } 


/* shouldComponentUpdate(nextProps) { 
    if (this.props !== nextProps) { 
     return true; 
    } 
    return false; 
    } */ 

    deleteRow(secId, rowId, rowMap) { 
    // rowMap[`${secId}${rowId}`].closeRow(); 
    //console.log('delete', secId, rowId, rowMap); 

    // const newData = [...this.state.listViewData]; 
    // newData.splice(rowId, 1); 
    // this.setState({ listViewData: newData }); 
    } 

    render() { 
     //const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 }); 
     //const dataSource = ds.cloneWithRows(receiptlist); 
     //this.ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 }); 
     return (
      <BackgroundView style={styles.container}> 
       <View style={styles.search}> 
        <MySearchBar /> 
        <Button style={styles.button}> Export </Button> 
       </View> 
       <SwipeListView 
         dataSource={this.state.listViewData} 
         renderRow={(data) => this.renderRow(data)} 
         renderHiddenRow={(secId, rowId, rowMap) => this.renderHiddenRow(secId, rowId, rowMap)} 
         rightOpenValue={-150} 
         recalculateHiddenLayout 
         previewFirstRow 
       /> 
       <FAB 
      onPress={this.onPressFAB} 
       /> 
      </BackgroundView> 
     ); 
    } 

renderRow(data) { 
     console.log('data', data); 
     return (
      <TouchableHighlight 
       onPress={console.log('You touched me')} 
       style={styles.rowFront} 
       underlayColor={'#AAA'} 
      > 
       <View> 
        <View style={{ flexDirection: 'row', justifyContent: 'space-between' }} > 
         <Text> {`${data.vendor}`} </Text> 
         <Text> {`${data.total}`} </Text> 
        </View> 
        <View> 
         <Text> {`${data.date}`} </Text> 
         <Text> {`${data.category}`} </Text> 
        </View> 
       </View> 
      </TouchableHighlight> 
     ); 
    } 

    renderHiddenRow(secId, rowId, rowMap) { 
     return (
     <View style={styles.rowBack}> 
      <TouchableOpacity 
       style={[styles.backRightBtn, styles.backRightBtnLeft]} 
       onPress={_ => (console.log(secId, rowId, rowMap))} 
      > 
       <Text style={styles.backTextWhite}>Export</Text> 
      </TouchableOpacity> 
      <TouchableOpacity 
       style={[styles.backRightBtn, styles.backRightBtnRight]} 
       onPress={_ => (console.log(secId, rowId, rowMap))} 
      > 
       <Text style={styles.backTextWhite}>Delete</Text> 
      </TouchableOpacity> 
     </View> 
     ); 
    } 

    onPressFAB() { 
    console.log('FAB pressed'); 
    Alert.alert(
     'Choose Photo Source', 
     null, 
     [ 
     { text: 'Camera', onPress:() => Actions.camera() }, 
     { text: 'Photo Library', onPress:() => Actions.photos() }, 
     { text: 'Cancel', onPress:() => console.log('cancel'), style: 'cancel' } 
     ] 
    ); 
    } 
} 

const styles = { 
    search: { 
    flexDirection: 'row', 
    padding: 10, 
    height: 60, 
    backgroundColor: PRIMARY_HIGHLIGHT_COLOUR 
    }, 
    button: { 
    marginTop: 0, 
    height: 30, 
    flexGrow: 0.3 
    }, 
    container: { 
    padding: 0, 
    paddingTop: HEADER.height 
    }, 
    rowFront: { 
     //alignItems: 'center', 
    flex: 1, 
    padding: 10, 
     backgroundColor: CARD_BACKGROUND_COLOUR, 
     borderBottomColor: BORDER_COLOUR, 
     borderBottomWidth: 1, 
     justifyContent: 'center', 
     //height: 100, 
    }, 
    rowBack: { 
     alignItems: 'center', 
     backgroundColor: '#DDD', 
     flex: 1, 
     flexDirection: 'row', 
     justifyContent: 'space-between', 
     paddingLeft: 15, 
    }, 
    backRightBtn: { 
     alignItems: 'center', 
     bottom: 0, 
     justifyContent: 'center', 
     position: 'absolute', 
     top: 0, 
     width: 75 
    }, 
    backRightBtnLeft: { 
     backgroundColor: 'blue', 
     right: 75 
    }, 
    backRightBtnRight: { 
     backgroundColor: 'red', 
     right: 0 
    }, 
    controls: { 
     alignItems: 'center', 
     marginBottom: 30 
    }, 
    switchContainer: { 
     flexDirection: 'row', 
     justifyContent: 'center', 
     marginBottom: 5 
    }, 
    switch: { 
     alignItems: 'center', 
     borderWidth: 1, 
     borderColor: 'black', 
     paddingVertical: 10, 
     width: 100, 
    } 
}; 

const mapStateToProps = ({ receipts, accounts }) => { 
    const { 
    myReceipts, 
     receiptList 
    } = receipts; 
    const { 
    labelsArray 
    } = accounts; 
    return { 
    myReceipts, 
    receiptList, 
    labelsArray 
    }; 
}; 

export default connect(mapStateToProps, { 
})(ReceiptsListView); 
+1

您是如何解決問題的?我有類似的,你會介意回答你自己的問題嗎? – milkersarac

+1

我的第一個建議是使用同一個庫中提供的''組件,並使用內建的'ListView',看看它是否適合你。 –

+0

此外,爲什麼這是downvoted。這是顯示所有代碼的問題。不妨刪除整件事,讓其他人都可以從中受益,這要歸功於一些幫助。如果您想複製它,將明天刪除E​​nie –

回答

3

的問題是柔性:1的renderRow造型

下面是工作代碼,我敢肯定,它可以幫助他人(風格 rowFront)。

import React, { 
    Component, 
} from 'react'; 
import { 
    ListView, 
    Text, 
    TouchableOpacity, 
    TouchableHighlight, 
    View, 
    Alert, 
    TextInput 
} from 'react-native'; 
import { connect } from 'react-redux'; 
import { Actions } from 'react-native-router-flux'; 
import { SwipeListView } from 'react-native-swipe-list-view'; 
import Icon from 'react-native-vector-icons/FontAwesome'; 
import Spinner from 'react-native-loading-spinner-overlay'; 

import { 
    PRIMARY_HIGHLIGHT_COLOUR, 
    CARD_BACKGROUND_COLOUR, 
    BORDER_COLOUR, 
    SHADOW_COLOUR 
} from '../global/colours'; 
import { 
    Button, 
    FAB, 
    BackgroundView, 
    TitleText 
} from '../components'; 
import { HEADER } from '../global/margins'; 
import { searchTextChanged, deleteReceipt } from '../actions'; 

class ReceiptsListView extends Component { 

    constructor(props) { 
     super(props); 
     console.log(this.props.receiptList); 
     console.log(this.props.categories); 
     this.ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 }); 
    } 

    shouldComponentUpdate(nextProps) { 
    if (this.props !== nextProps) { 
     return true; 
    } else if (this.props.searchQuery !== nextProps.searchQuery) { 
      return true; 
     } 
    return false; 
    } 

    render() { 
     if (this.props.receiptList.length < 1) { 
      return (
       <BackgroundView style={styles.emptyContainer}> 
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> 
         <TitleText> No Receipts </TitleText> 
        </View> 
        <FAB 
         onPress={this.onPressFAB} 
        /> 
       </BackgroundView> 
      ); 
     } 
     return (
      <BackgroundView style={styles.container}> 
       <View style={styles.search}> 
         <View style={{ flexGrow: 1, height: 35, paddingTop: 5 }}> 
          <View style={styles.searchStyle}> 
           <View style={styles.searchbar}> 
            <Icon 
             name="search" 
             size={15} 
             color="#ddd" 
            /> 
            <TextInput 
             style={{ flexGrow: 1, width: null, paddingLeft: 5 }} 
             placeholder='search' 
             placeholderTextColor='lightgray' 
             onChangeText={this.onSearchChange.bind(this)} 
             value={this.props.searchQuery} 
             onFocus={() => console.log('hi')} 
            /> 
           </View> 
          </View> 
         </View> 
         <Button 
          style={styles.button} 
          //onPress={this.searchText()} 
         > 
          Search 
         </Button> 
        </View> 
       <SwipeListView 
         dataSource={this.ds.cloneWithRows(this.props.receiptList)} 
         renderRow={(data) => this.renderRow(data)} 
         renderHiddenRow={(secId, rowId, rowMap) => this.renderHiddenRow(secId, rowId, rowMap)} 
         rightOpenValue={-150} 
         recalculateHiddenLayout 
         previewFirstRow 
       /> 
       <FAB 
      onPress={this.onPressFAB} 
       /> 
       <Spinner 
        visible={this.props.isFetching} 
        textContent={''} 
        textStyle={{ color: 'white' }} 
       /> 
      </BackgroundView> 
     ); 
    } 

    onSearchChange(text) { 
     this.props.searchTextChanged(text); 
    } 

    renderRow(data) { 
     //console.log('data', data); 
     return (
       <TouchableHighlight 
        onPress={() => console.log('You touched me', data)} 
        underlayColor={'#AAA'} 
        style={styles.rowFront} 
       > 
        <View> 
         <View style={{ flexDirection: 'row', justifyContent: 'space-between' }} > 
          <Text> {`${data.vendor}`} </Text> 
          <Text> {`${data.total}`} </Text> 
         </View> 
         <View> 
          <Text> {`${data.date}`} </Text> 
          <Text> {`${data.category}`} </Text> 
         </View> 
        </View> 
       </TouchableHighlight> 
     ); 
    } 

    renderHiddenRow(secId, rowId, rowMap) { 
     return (
     <View style={styles.rowBack}> 
      <TouchableOpacity 
       style={[styles.backRightBtn, styles.backRightBtnLeft]} 
       onPress={() => (this.exportItem(secId, rowId, rowMap))} 
      > 
       <Text style={styles.backTextWhite}>Export</Text> 
      </TouchableOpacity> 
      <TouchableOpacity 
       style={[styles.backRightBtn, styles.backRightBtnRight]} 
       onPress={() => (this.deleteItem(secId, rowId, rowMap))} 
      > 
       <Text style={styles.backTextWhite}>Delete</Text> 
      </TouchableOpacity> 
     </View> 
     ); 
    } 

    deleteItem(secId, rowId, rowMap) { 
     console.log('secId', secId, 'rowId', rowId, 'rowMap', rowMap); 
     console.log('obj', secId.id, 'acc', this.props.curAccountID); 
     this.props.deleteReceipt(this.props.curAccountID, secId.id); 
    } 

    exportItem(secId, rowId, rowMap) { 
     console.log('secId', secId, 'rowId', rowId, 'rowMap', rowMap); 
     //this.props.exportReceipt(this.props.curAccountID, secId.id); 
    } 

    onPressFAB() { 
    console.log('FAB pressed'); 
    Alert.alert(
     'Choose Photo Source', 
     null, 
     [ 
     { text: 'Camera', onPress:() => Actions.camera() }, 
     { text: 'Photo Library', onPress:() => Actions.photos() }, 
     { text: 'Cancel', onPress:() => console.log('cancel'), style: 'cancel' } 
     ] 
    ); 
    } 
} 

const styles = { 
    search: { 
    flexDirection: 'row', 
    padding: 10, 
    height: 60, 
    backgroundColor: PRIMARY_HIGHLIGHT_COLOUR 
    }, 
    searchbar: { 
     flex: 1, 
     flexDirection: 'row', 
     justifyContent: 'space-between', 
     paddingLeft: 5 
    }, 
    button: { 
    marginTop: 0, 
    height: 30, 
    flexGrow: 0.3 
    }, 
    container: { 
    padding: 0, 
    paddingTop: HEADER.height 
    }, 
    emptyContainer: { 
     flex: 1, 
     padding: 0, 
     paddingTop: HEADER.height, 
     justifyContent: 'center' 
    }, 
    rowFront: { 
     //alignItems: 'center', 
    padding: 10, 
     backgroundColor: CARD_BACKGROUND_COLOUR, 
     borderBottomColor: BORDER_COLOUR, 
     borderBottomWidth: 1, 
     justifyContent: 'center', 
     //height: 100, 
    }, 
    rowBack: { 
     alignItems: 'center', 
     backgroundColor: '#DDD', 
     flex: 1, 
     flexDirection: 'row', 
     justifyContent: 'space-between', 
     paddingLeft: 15, 
    }, 
    backRightBtn: { 
     alignItems: 'center', 
     bottom: 0, 
     justifyContent: 'center', 
     position: 'absolute', 
     top: 0, 
     width: 75 
    }, 
    backRightBtnLeft: { 
     backgroundColor: 'blue', 
     right: 75 
    }, 
    backRightBtnRight: { 
     backgroundColor: 'red', 
     right: 0 
    }, 
    controls: { 
     alignItems: 'center', 
     marginBottom: 30 
    }, 
    switchContainer: { 
     flexDirection: 'row', 
     justifyContent: 'center', 
     marginBottom: 5 
    }, 
    switch: { 
     alignItems: 'center', 
     borderWidth: 1, 
     borderColor: 'black', 
     paddingVertical: 10, 
     width: 100, 
    }, 
    searchStyle: { 
     flex: 1, 
     flexDirection: 'row', 
     alignSelf: 'stretch', 
     padding: 5, 
     justifyContent: 'flex-start', 
     alignItems: 'center', 
     backgroundColor: CARD_BACKGROUND_COLOUR, 
     borderRadius: 10, 
     borderWidth: 1, 
     borderColor: 'grey', 
     marginLeft: 5, 
     marginRight: 5, 
     shadowColor: SHADOW_COLOUR, 
     shadowOffset: { width: 0, height: 2 }, 
     shadowOpacity: 0.1, 
     shadowRadius: 2, 
    }, 
}; 

const mapStateToProps = ({ accounts, receipts, searchIt }) => { 
    const { 
     curAccountID 
    } = accounts; 
    const { 
     searchQuery 
    } = searchIt; 
    const { 
     isFetching, 
    myReceipts, 
     receiptList, 
     categories 
    } = receipts; 
    return { 
     curAccountID, 
     isFetching, 
    myReceipts, 
     receiptList, 
     searchQuery, 
     categories 
    }; 
}; 

export default connect(mapStateToProps, { 
     searchTextChanged, deleteReceipt 
})(ReceiptsListView); 
+1

感謝您的回答。這正是我所擁有的東西,它解決了我的問題。 – milkersarac

+0

好東西,謝謝 –

+0

@Ally Haire謝謝你的回答。我提出了你的問題並給了它一顆星星。 –