【问题标题】:How do i navigate to a new screen from FlatList?如何从 FlatList 导航到新屏幕?
【发布时间】:2025-12-14 14:50:01
【问题描述】:

单击我的 FlatList 中的项目时,我想导航到一个名为 GridVid 的屏幕。我无法弄清楚如何做到这一点,因为

onPress={() => this.props.navigation.navigate('GridVid')}

只有在定义 StackNavigator 时在 App.js 中调用才会起作用,而不是 ListItem 类(在名为 ListItem.js 的单独文件中)

//App.js

class SettingsClass extends Component {

    constructor(props) {
      super(props)

      this.state = {
        columns: 3, //Columns for Grid
      };   
    }


  render() {
     const {columns} = this.state
      return (

         <View style={styles.grid}>
            <FlatList
                  numColumns={columns}         
                  data={[
                    {uri:'https://randomuser.me/api/portraits/thumb/women/12.jpg'},
                    {uri:'https://randomuser.me/api/portraits/thumb/women/13.jpg'},
                    {uri:'https://randomuser.me/api/portraits/thumb/women/14.jpg'},
                  ]}
                  renderItem={({item}) => {            
                      return (<ListItem itemWidth={(ITEM_WIDTH-(10*columns))/columns} 
                                        image={item}                                           
                              />                                
                            )
                       }}
                  keyExtractor={
                     (index) => { return index } 
                  } 
            />
         </View>
      );
  }
}

//Settings Class swipes to GridVid
const SettingsStack = createStackNavigator({
  SettingsScreen: {
    screen: SettingsClass
  },
  GridVid: {
    screen: GridVidClass
  },
});

//ListItem.js

export default class ListItem extends Component {

    state = {
       animatepress: new Animated.Value(1)
    }

    animateIn() {
        Animated.timing(this.state.animatepress, {
            toValue: 0.90,
            duration: 200
        }).start()
    }

    animateOut() {
      Animated.timing(this.state.animatepress, {
          toValue: 1,
          duration: 200
      }).start()
  }   

    render() {
      const {itemWidth} = this.props
      return (
          <TouchableWithoutFeedback
             onPressIn={() => this.animateIn()}
             onPressOut={() => this.animateOut()} 
             onPress={() => this.props.navigation.navigate('GridVid')} //WONT WORK HERE in this file!!!!
             >       
             <Animated.View style={{
                margin:5,
                transform: [{scale: this.state.animatepress}] }}>

                  <Image style={{width:itemWidth, height: 100}} source={this.props.image}></Image>   

             </Animated.View>
          </TouchableWithoutFeedback>

        );
    }

  }

//GridVid.js

export default class GridVidClass extends Component {

    render() {
      return (
        <View style={styles.container}> 
             <Text>On GridVid </Text>

        </View> 
        );
    }

  }

有什么方法可以在 FlatList(或 App.js 中的任何位置)中调用 onPress={() =&gt; this.props.navigation.navigate('GridVid') 而不是 ListItem(目前无法使用)?然而,在 ListItem 中,至少我正在单击我想要的图像并且对我正在单击的内容有一些参考。

【问题讨论】:

    标签: reactjs react-native react-navigation react-native-flatlist


    【解决方案1】:

    您需要做的是将onPress 属性传递给您的ListItem,这将使导航发生。

    //App.js

    class SettingsClass extends Component {
    
        constructor(props) {
          super(props)
    
          this.state = {
            columns: 3, //Columns for Grid
          };   
        }
    
    
      render() {
         const {columns} = this.state
          return (
    
             <View style={styles.grid}>
                <FlatList
                      numColumns={columns}         
                      data={[
                        {uri:'https://randomuser.me/api/portraits/thumb/women/12.jpg'},
                        {uri:'https://randomuser.me/api/portraits/thumb/women/13.jpg'},
                        {uri:'https://randomuser.me/api/portraits/thumb/women/14.jpg'},
                      ]}
                      renderItem={({item}) => {            
                          return (<ListItem itemWidth={(ITEM_WIDTH-(10*columns))/columns} 
                                            image={item}        
                                            onPress={() => this.props.navigation.navigate('GridVid') // passing the onPress prop 
                                  />                                
                                )
                           }}
                      keyExtractor={
                         (index) => { return index } 
                      } 
                />
             </View>
          );
      }
    }
    
    //Settings Class swipes to GridVid
    const SettingsStack = createStackNavigator({
      SettingsScreen: {
        screen: SettingsClass
      },
      GridVid: {
        screen: GridVidClass
      },
    });
    

    //ListItem.js

    export default class ListItem extends Component {
    
        state = {
           animatepress: new Animated.Value(1)
        }
    
        animateIn() {
            Animated.timing(this.state.animatepress, {
                toValue: 0.90,
                duration: 200
            }).start()
        }
    
        animateOut() {
          Animated.timing(this.state.animatepress, {
              toValue: 1,
              duration: 200
          }).start()
      }   
    
        render() {
          const {itemWidth} = this.props
          return (
              <TouchableWithoutFeedback
                 onPressIn={() => this.animateIn()}
                 onPressOut={() => this.animateOut()} 
                 onPress={this.props.onPress} // using onPress prop to navigate
                 >       
                 <Animated.View style={{
                    margin:5,
                    transform: [{scale: this.state.animatepress}] }}>
    
                      <Image style={{width:itemWidth, height: 100}} source={this.props.image}></Image>   
    
                 </Animated.View>
              </TouchableWithoutFeedback>
    
            );
        }
    
      }
    

    【讨论】:

    • 嗨 Vencovsky,ListItem 中的 onPress={this.props.onPress} 应该放在哪里?随意编辑 OP 中的 ListItem.js 文件
    • @chai86 这个用完整的组件和你应该添加的地方编辑
    • 行得通!!!谢谢!!!!!!!我想做的另一件事是在我按下时将属性(字符串)传递给 GridVidClass。我在想这样的事情:this.props.navigation.navigate('GridVid', "my_string")。这是正确的,是完全不正确的吗?
    • 您的意思是要向GridVid 传递其他数据?检查the docs
    【解决方案2】:

    ListItem 不在 StackNavigator 中,所以它不知道导航是什么

    您可以像 Vencovsky 的回答一样使用或从 ListItem 的父组件传递导航道具

    <ListItem 
       itemWidth={(ITEM_WIDTH-(10*columns))/columns} 
       image={item} 
       navigation={this.props.navigation}                                   
    />
    

    【讨论】:

    • 你好。那么我将如何在 App.js 中调用它?