简体   繁体   English

带有导航的React-Native ListView

[英]React-native ListView with Navigation

I am trying to use component ListView with Navigation but I get undefined is not an object (evaluating'_this.props.navigator') error 我正在尝试将组件ListView与Navigation一起使用,但未定义不是对象(正在评估'_this.props.navigator')错误

My ListView is in Contacts.js 我的ListView在Contacts.js中

import React, { Component } from 'react';
import { AppRegistry, StyleSheet, ListView, Text, View, Navigator  } from 'react-native';
import Row from './Row'
import SearchBar from './SearchBar'
import Sections from './Sections'
import Load from './Load'
import demoData from './data'
import Pagination from '../Pagination';

export default class Contacts extends React.Component{
    constructor(props) {
        super(props)

        const getSectionData = (dataBlob, sectionId) => dataBlob[sectionId];
        const getRowData = (dataBlob, sectionId, rowId) => dataBlob[`${rowId}`];

        const ds = new ListView.DataSource({
          rowHasChanged: (r1, r2) => r1 !== r2,
          sectionHeaderHasChanged : (s1, s2) => s1 !== s2,
          getSectionData,
          getRowData,
        });

        const { dataBlob, sectionIds, rowIds } = this.formatData(demoData);

        // Init state
        this.state = {
            dataSource: ds.cloneWithRowsAndSections(dataBlob, sectionIds, rowIds),
            left: true,
            center: false,
            right: false
        }
    }

formatData(data) {
    // We're sorting by alphabetically so we need the alphabet
    const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');

    // Need somewhere to store our data
    const dataBlob = {};
    const sectionIds = [];
    const rowIds = [];

    // Each section is going to represent a letter in the alphabet so we loop over the alphabet
    for (let sectionId = 0; sectionId < alphabet.length; sectionId++) {
        // Get the character we're currently looking for
        const currentChar = alphabet[sectionId];

        // Get users whose first name starts with the current letter
        const users = data.filter((user) => user.name.first.toUpperCase().indexOf(currentChar) === 0);

        // If there are any users who have a first name starting with the current letter then we'll
        // add a new section otherwise we just skip over it
        if (users.length > 0) {
            // Add a section id to our array so the listview knows that we've got a new section
            sectionIds.push(sectionId);

            // Store any data we would want to display in the section header. In our case we want to show
            // the current character
            dataBlob[sectionId] = { character: currentChar };

            // Setup a new array that we can store the row ids for this section
            rowIds.push([]);

            // Loop over the valid users for this section
            for (let i = 0; i < users.length; i++) {
                // Create a unique row id for the data blob that the listview can use for reference
                const rowId = `${sectionId}:${i}`;

                // Push the row id to the row ids array. This is what listview will reference to pull
                // data from our data blob
                rowIds[rowIds.length - 1].push(rowId);

                // Store the data we care about for this row
                dataBlob[rowId] = users[i];
            }
        }
    }

    return { dataBlob, sectionIds, rowIds };
    }

    render() {
        return (
            <View style={styles.contactsContainer} >
                <Pagination 
                    left={this.state.left}
                    center={this.state.center}
                    right={this.state.right}
                />
                <ListView
                style={styles.listContainer}
                dataSource={this.state.dataSource}
                renderRow={(data) => <Row {...data} navigator={this.props.Navigator} />}
                renderSeparator={(sectionId, rowId) => <View key={rowId} style={styles.separator} />}
                renderHeader={() => <SearchBar />}
                renderFooter={() => <Load />}
                renderSectionHeader={(sectionData) => <Sections {...sectionData} />}
                />
            </View>
        );
    }
}

const styles = StyleSheet.create({
    contactsContainer: {
        flex: 1
    },
    listContainer: {
        marginTop: 10
    },
    separator: {
        flex: 1,
        height: StyleSheet.hairlineWidth,
        backgroundColor: '#8E8E8E',
    }
});

Line 线

renderRow={(data) => } renderRow = {(数据)=>}

calls Row.js and prints contacts data 调用Row.js并打印联系人数据

import React from 'react';
import ProfileScreen from './ProfileScreen'
import { AppRegistry, View, Text, StyleSheet, TouchableHighlight, Alert, Navigator } from 'react-native';

const Row = (props) => (
    <TouchableHighlight onPress={() => this.props.Navigator.push({ screen: 'ProfileScreen' })} underlayColor="#FFFFFF">
        <View style={ styles.container }>
            <View style={ styles.status } />
            <Text style={ styles.text }>
                {`${ props.name.first } ${ props.name.last }`}
            </Text>
        </View>
    </TouchableHighlight>
);

const styles = StyleSheet.create({
    container: {
        flex: 1,
        padding: 12,
        flexDirection: 'row',
        alignItems: 'center',
    },
    text: {
        marginLeft: 12,
        fontSize: 16,
    },
    status: {
        backgroundColor: '#5cb85c',
        height: 10,
        width: 10,
        borderRadius: 20,
    },
});

export default Row;

As you can see each row has a TouchableHighlight when pressed it should navigate to ProfileScreen 如您所见,每行在按下时都有一个TouchableHighlight,应该导航到ProfileScreen

EDIT 编辑

DO NOT USE NAVIGATOR IT IS DEPRECIATED INSTED USE STACKNAVIGATOR 请勿使用导航仪,它已被弃用。

There is no need to use this.props.Navigator when you are importing the Navigator module. 导入导航器模块时,无需使用this.props.Navigator。 Just use Navigator. 只需使用导航器。 this.props contains the list of all the attributes that you pass on to a component this.props包含传递给组件的所有属性的列表

Eg: 例如:

Parent.js Parent.js

class Parent extends React.Component {
  render() {
    <Child firstProp={"FirstProp"} secondProps={"SecondProp"} />
  }
}    

Child.js Child.js

import {externalImport} from './externalFile'

class Child extends React.Component{
  render() {
    <div>
       I AM FIRST PROP {this.props.firstProp}
       I AM SECOND PROP {this.props.secondProp}
       I AM NOT A PROP, JUST AN IMPORT { externalImport }
    </div>
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM