开发者问题收集

使用无状态组件中的 Flatlist 来响应原生导航

2018-03-26
2845

我正在尝试创建无状态组件来显示 Flatlist,但在导航方面却遇到了困难。

这是我的“主”app.js,已精简:

import React from 'react';
import { AppRegistry, FlatList, ActivityIndicator, Text, View, Image, StyleSheet } from 'react-native';
import { StackNavigator } from 'react-navigation'
import Strip from '../components/Strip'

export default class FetchData extends React.Component {

    constructor(props){
        super(props);
        this.state ={ isLoading: true}
    }

    componentDidMount(){
        ...
    }


    render(){
        if(this.state.isLoading){
            ...
        }
        return (
            <View>
                <Strip props={this.state.dataSource.strips} />
            </View>
        )
    }
}

这是组件:

import React from 'react';
import { FlatList, Text, View, Image, StyleSheet, TouchableOpacity } from 'react-native';

renderItem = ({item}) => (
    <TouchableOpacity onPress={() => this.props.navigation.navigate('Details')} >
        <View style={{width: 136}}>
            ...
            <Text>some text</Text>
        </View>
    </TouchableOpacity>
);

const Strip = (props) => {
    return Object.keys(props).map(function(key, i) {
        return Object.keys(props[key]).map((strips, i) => {
            var strip = props[key][strips];
            return(
                <View>
                    <Text>{strip.title}</Text>
                    <FlatList horizontal
                        data={strip.someobjects}
                        renderItem={({item}) => this.renderItem(item)}
                    />     
                </View>
            )
        });
    })
}

export default Strip;

列表已显示,但是,当然,当我触摸某个项目时,会出现“未定义不是对象(评估'_this.props.navigation')”错误。

我知道不能在无​​状态组件上使用 this.props.navigation.navigate,但我只是不明白如何通过无状态组件中的 flatlist 传递导航道具。

它必须非常简单,例如使用 navigate('Details') 并将 const { navigation } = this.props.navigation; 放在某处。但是在哪里呢?

2个回答

不要从 Strip 组件进行 navigate ,而是为 Strip 提供 onPress 处理程序并从那里进行导航。如果 FetchDataStackNavigator 的一部分,那么您可以轻松地从此组件进行 navigate

请考虑以下示例

...
export default class FetchData extends React.Component {
 ...
 handleOnPress = () => {
  this.props.navigation.navigate('Details')
 }

 render() {
  if(this.state.isLoading){
   ...
  }
  return (
   <View>
    <Strip 
     props={this.state.dataSource.strips} 
     onPress={this.handleOnPress} 
    />
   </View>
  );
 }
}

Strip 组件中,您可以绑定 onPress 处理程序

 const Strip = (props) => {
  renderItem = ({item}) => (
   <TouchableOpacity onPress={props.onPress} >
    <View style={{width: 136}}>
     ...
    <Text>some text</Text>
   </View>
  </TouchableOpacity>
 );

 return Object.keys(props).map(function(key, i) {
  return Object.keys(props[key]).map((strips, i) => {
   var strip = props[key][strips];
    return(
     <View>
      <Text>{strip.title}</Text>
       <FlatList horizontal
         data={strip.someobjects}
         renderItem={({item}) => renderItem(item)}
       />     
      </View>
     )
  });
})
}

希望这会有所帮助!

Prasun
2018-03-26

在父级中定义一个导航函数,并通过 props 将其传递给子级。

例如:

父级


parentNavigate(destination){
 this.props.navigation.navigate(destination);
}

render(){
        if(this.state.isLoading){
            ...
        }
        return (
            <View>
                <Strip props={this.state.dataSource.strips} parentNavigate={(destination) => this.parentNavigate(destination)}/>
            </View>
        )
    }

子级


renderItem = (item, parentNavigate) => (
    <TouchableOpacity onPress={parentNavigate('Details')} >
        <View style={{width: 136}}>
            ...
            <Text>some text</Text>
        </View>
    </TouchableOpacity>
);

const Strip = (props, parentNavigate) => {
    return Object.keys(props).map(function(key, i) {
        return Object.keys(props[key]).map((strips, i) => {
            var strip = props[key][strips];
            return(
                <View>
                    <Text>{strip.title}</Text>
                    <FlatList horizontal
                        data={strip.someobjects}
                        renderItem={(item, parentNavigate) => this.renderItem(item, parentNavigate)}
                    />     
                </View>
            )
        });
    })
}
Harikrishnan
2018-03-26