带有导航的 React-native ListView
Posted
技术标签:
【中文标题】带有导航的 React-native ListView【英文标题】:React-native ListView with Navigation 【发布时间】: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
的父组件。
我在每个文件上都定义了导航器。我发布了整个文件,以便您查看。
以下答案是否解决了问题?
【参考方案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 已经贬值了。以上是关于带有导航的 React-native ListView的主要内容,如果未能解决你的问题,请参考以下文章