【问题标题】:React-native ListView with Navigation带有导航的 React-native ListView
【发布时间】:2018-04-24 23:17:53
【问题描述】:

我正在尝试将组件 ListView 与 Navigation 一起使用,但我得到 undefined is not an object (evalating'_this.props.navigator') 错误

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

线

renderRow={(数据) => }

调用 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;

如您所见,每一行在按下时都有一个 TouchableHighlight,它应该导航到 ProfileScreen

编辑

不要使用 NAVIGATOR,它已被弃用 INSTED USE STACKNAVIGATOR

【问题讨论】:

  • 请贴出定义navigator的父组件。
  • 我在每个文件上都定义了导航器。我发布了整个文件,以便您查看。
  • 以下答案是否解决了问题?

标签: javascript listview react-native navigation


【解决方案1】:

在导入 Navigator 模块时无需使用 this.props.Navigator。只需使用导航器。 this.props 包含您传递给组件的所有属性的列表

例如:

Parent.js

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

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>
  }
}

【讨论】:

  • 你说得对,但我发现 Navigator 已经贬值了。
猜你喜欢
  • 2017-06-24
  • 1970-01-01
  • 2018-08-05
  • 1970-01-01
  • 2021-12-17
  • 2017-07-24
  • 2021-07-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多