如何访问无法访问this.props.navigation的功能组件或类组件内部的react-navigation?

问题描述 投票:3回答:5

我正在使用expo在react本机平台内执行此操作。

我想显示项目列表(ListItems.js)All_Employees_screen.js。这些项目是通过功能组件呈现的,我希望有一个onRowPress()处理程序,以便在点击它时我可以将其导航到另一个视图,但我不知道如何在反应导航上做到这一点?

或者因为新的功能组件可以是类组件(这会更好)如何访问其中的导航内容?

enter image description here

AllProperties.js

import _ from 'lodash';
import React, {
  Component
} from 'react';

import {
  Button,
  ListView,
  ScrollView
} from 'react-native';


import ListItem from './ListItem';
import { connect } from 'react-redux';
import { propertiesFetch } from '../../actions';

// import { FormLabel, FormInput } from 'react-native-elements'

class AllPropertiesScreen extends React.Component {

  componentWillMount(){
    this.props.propertiesFetch();
    this.createDataSource(this.props);
  }

// we do this componentWillMount & componentWillReceiveProps (nextProps) thing twice, coz once the component is
// loaded it loads all teh values but when user hits another view like Create property, The Property data still exists
// in the global state object,

// we could move all the  dc dataSource code into componentWillReceiveProps but its actually gonna benefit us
 // if we make sure that we try to build our data source both when the component first loads up
// & when second time  after we go back and forth other compoennts.

  componentWillReceiveProps(nextProps){
    // nextProps are the next set of props that this component will be rendered with
    // this.props is still the old set of props
    this.createDataSource(nextProps);
  }


createDataSource({ properties }){
  const ds = new ListView.DataSource({
        rowHasChanged: (r1, r2) => r1 !== r2
      });
      this.dataSource = ds.cloneWithRows(properties);
}


    static navigationOptions = ({ navigation }) => {
      const {state, setParams} = navigation;
      return {
        title: 'All Emplooyee',
        headerRight: (
          <Button
            title='Add'
            // onPress={() => setParams({ mode: isInfo ? 'none' : 'info'})}
             onPress={() => navigation.navigate('createProperty')
             }
          />
        ),
      };
    };

goBack(){
    console.log('65 - go Back clicked');
}

renderRow(property){
  // console.log('67-AllPropertiesScreen  =', property);
  return <ListItem property={property}
      onPress={() => { console.log('65 - go Back clicked')  }}
    />;
}

  render() {
    console.log('72-AllPropertiesScreen  this.props', this.props );
    return(
        <ListView
          enableEmptySections
          dataSource={this.dataSource}
          renderRow={this.renderRow}
        />
    );
  }
}

const mapStateToProps = state => {
  console.log('83 - AllPropertiesScreen  state. properties', state );
  const properties = _.map(state.properties, (val, uid ) => {
      return { ...val, uid };  //   { shift: 'Monday'}
  });

  return { properties };
};

export default connect(mapStateToProps, {propertiesFetch}) (AllPropertiesScreen);

ListItem.js

import React, { Component } from 'react';
import { Text, TouchableWithoutFeedback, View } from 'react-native';

class ListItem extends Component {

  // onRowPress(){
  //   Actions.employeeEdit({ employee: this.props.employee });
  // }

  render(){
    const { agent_name, cell, address } = this.props.property;
    console.log('14- ListItem ', this.props);

    return (
        <View>
          <CardSection>
            <Text style={styles.titleStyle}>
                name
            </Text>
            <Text style={styles.titleStyle}>
              cell
            </Text>
            <Text style={styles.titleStyle}>
              address
            </Text>
          </CardSection>
      </View>
    );
  }
}

const styles = {
  titleStyle: {
    fontSize: 18,
    paddingLeft: 15
  }
}

export default ListItem;

//

main.js(这是我拥有所有导航路径的地方。

class App extends React.Component {
  render() {
    const MainNavigator = TabNavigator({
          // auth: { screen : AuthScreen },
          // review: { screen: ReviewScreen },  
          // signup: { screen : SignupScreen }, 
          followup: { screen: FollowupScreen },               welcome: { screen : WelcomeScreen },
          auth: { screen : AuthScreen },
          signup: { screen : SignupScreen },
          main: {
            screen: TabNavigator ({
              followup: { screen: FollowupScreen },
              map: { screen: MapScreen },
              deck: { screen: DeckScreen },
              settings : {
                screen: StackNavigator ({
                  settings: { screen: SettingsScreen },
                  // settings: { screen: SettingsScreen },
                  UserProfile: { screen: UserProfileScreen },
                  HelpSupport: { screen: HelpSupportScreen },
                  Notifications: { screen: NotificationsScreen },
                  Signout: { screen: SignoutScreen }   // not working, Navigation object not accessible inside the component
                })  //screen: StackNavigator ({
              },
              followup : {
                screen: StackNavigator ({
                  followup: { screen: FollowupScreen },
                  allProperties: { screen: AllPropertiesScreen },
                  createProperty: { screen: PropertyCreateScreen },
                  Red: { screen: RedPriorityScreen },   // not working, Navigation object not accessible inside the component
                  GreyPriority: { screen: GreyPriorityScreen },

                })  //screen: StackNavigator ({
              },
              draw: {
                screen: DrawerNavigator ({
                  drawin: { screen: DrawScreen },
                })  //screen: StackNavigator ({
              }
            }) //screen: TabNavigator
          }
    }, {
      navigationOptions: {
          tabBarVisible: false
      },
      lazy: true
});

return (
  <Provider store={store}>
    <View style={styles.container}>
      <MainNavigator />
    </View>
  </Provider>
);
}
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    // alignItems: 'center',
    justifyContent: 'center',
  },
});

Expo.registerRootComponent(App);

@Matt建议的解决方案,但是只要我把导航= {this.props.navigation}抱怨就行了。 undefined不是对象(评估this.props.navigation)

renderRow(property){
  return (
    <ListItem
      property={property}
      navigation={this.props.navigation}
      onPress={() => {
        console.log( '70-on Press  inside renderRow ');
      }}/>
  );
}
react-native react-navigation expo
5个回答
3
投票

如果组件不是屏幕,则必须导入导航。

试试这个:

import React from 'react';
import { Button } 'react-native';
import { withNavigation } from 'react-navigation';

class MyBackButton extends React.Component {
  render() {
    return <Button title="Back" onPress={() => { this.props.navigation.goBack() }} />;
  }
}

// withNavigation returns a component that wraps MyBackButton and passes in the
// navigation prop
export default withNavigation(MyBackButton);

欲了解更多信息,请查看https://reactnavigation.org/docs/connecting-navigation-prop.html


3
投票

这个答案是为旧版本的react-navigation V1编写的

我有同样的问题,我发现this.props.navigation仅注入screenStackNavigator中注册为TabbNavigator的组件。

但一般来说你可以使用navigate类的NavigationActions(来源https://v1.reactnavigation.org/docs/navigation-actions.html#navigate

注意:NavigationActions.navigate以不同的方式接收参数,但工作方式相同。

所以这对我有用

import { NavigationActions } from 'react-navigation';
let {navigate} = NavigationActions;

renderRow(property) {
  return (
    <ListItem 
      property={property}
      onPress={() => { navigate({
        routeName: 'OtherRoute'
       });
    }}/>
  );
}    

1
投票
<MyComponent navigation={this.props.navigation}/>

主要问题在这里。您没有在组件中定义道具导航。你应该添加这个。


0
投票

将您的renderRow方法更改为以下内容:

renderRow(property) {
  return (
    <ListItem 
      property={property}
      onPress={() => { this.props.navigation.navigate('OtherRoute'); }}/>
  );
}

其中'OtherRoute'是您要导航到该行的路线的名称。


0
投票

以下是在功能组件中使用navigation.navigate的方法:

import { Text, TouchableHighlight } from 'react-native';

const MyComponent = ({ navigation }) => (
  <TouchableHighlight
    onPress={() => navigation.navigate('OtherRoute')}
    underlayColor="blue"/>
     <Text>Click to Navigate!</Text>
  </TouchableHighlight>
);

export default MyComponent;

渲染MyComponent时,您需要将导航作为道具传递。例如,假设HomeContainer是一个屏幕组件:

import React from 'react';
import MyComponent from './MyComponent';

export default HomeContainer extends React.Component {
  render() {
    return (
      <MyComponent navigation={this.props.navigation}/>
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.