将navigation.navigate传递给子组件

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

使用react-navigation构建应用程序。我有一个父组件,它从firebase中提取并在listview中呈现数据。列表视图渲染组件“ListName”具有onRowPress函数,但是this.props.navigation.navigate未定义,因为导航不在该子组件的状态中。

我尝试了多种方式将导航道具传递给孩子,并从孩子内部的反应导航中导入导航。什么都行不通。

谢谢!

这是我的rootStackNavigator:

const RootStackNavigator = StackNavigator(
  {
    Login: { screen: LoginScreen },
    Main: { screen: MainTabNavigator },
    Feedback: { screen: ProvideInstanceScreen }
  },
  {
    navigationOptions: () => ({
      //headerTitleStyle: {
        //fontWeight: 'normal',
        tabBarVisible: false,
        header: null
      //},
    }),
  }
);

这是我的父组件(在其状态下具有navigation.navigate)

import React from 'react';
import { ListView, StyleSheet, Text, Image } from 'react-native';
import { connect } from 'react-redux';
import _ from 'lodash';
import { MainButton, GenSection } from '../components/common';
import { namesFetch } from '../actions';
import ListName from '../components/ListName.js';

class ProvideScreen extends React.Component {

  static navigationOptions = {
    header: null,
  };


  componentWillMount() {
  //console.log('HOME HOME HOME  PRINT', this.props)
    this.props.namesFetch();

    this.createDataSource(this.props);
  }

  componentDidMount() {
    console.log('PROVIDE PROPS   PRINT', this.props)
    this.createDataSource(this.props);
  }

  componentWillReceiveProps(nextProps) {
    //nextProps are next set of props component is rendered with and this.props is still old props
    console.log('NEXT PROPS', nextProps)
    this.createDataSource(nextProps);
  }


  createDataSource({ names }) {
    var namesArray = names.map(function(a) {return [a.name, a.uid];});
    //console.log('NAMES ARRAY PRINT', namesArray)
    const ds = new ListView.DataSource({
      rowHasChanged: (r1, r2) => r1 !== r2
    });
    this.dataSource = ds.cloneWithRows(namesArray);
  }

  renderRow(user) {
    return <ListName name={user[0]} />;
  }


  render() {
    return (
      <Image
        source={require('../components/images/mainBG.png')}
        style={styles.containerStyle}>
        <Text style={styles.textStyle}>
          Provide Feedback
        </Text>
        <GenSection style={{paddingTop: 8}} />
        <ListView
          enableEmptySections
          dataSource={this.dataSource}
          renderRow={this.renderRow}
          removeClippedSubviews={false}
        />

    </Image>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingTop: 15,
    backgroundColor: '#fff',
  },
  containerStyle: {
    flex: 1,
    width: undefined,
    height: undefined,
    backgroundColor:'transparent'
  },
  textStyle:
  {
    paddingTop: 20,
    paddingLeft: 12,
    fontSize: 32,
    fontWeight: '200',
    color: '#597abc'
  }
});



const mapStateToProps = state => {
  //console.log('STATE PRINT', state.feedbackInput)
  const names = _.map(state.feedbackInput, (val) => {
    return { ...val};
  });
  //console.log('NAMES PRINT', names)
  return { names };
};  //this is lodash   .map iterates over key value pairs and run function which assigns data to groups array



export default connect(mapStateToProps, { namesFetch })(ProvideScreen);

这是我的子组件(在状态中没有navigation.navigate):

import React, { Component } from 'react';
import { Text, TouchableWithoutFeedback, View } from 'react-native';
import { connect } from 'react-redux';
import { ListButton } from './common';

class ListName extends Component {
  onRowPress() {
    console.log('ON ROW PRESS  PRINT', this.props)
    this.props.navigation.navigate('Feedback', this.props);
  }

  componentDidMount() {
    //console.log('LIST NAME LIST NAME  PRINT', this.props)
  }

  render() {
    const name = this.props.name;
    //console.log('LISTNAME PRINT', name)

    return (
      <TouchableWithoutFeedback onPress={this.onRowPress.bind(this)}>
        <View>
          <ListButton>
            <Text style={styles.titleStyle}>
              {name}
            </Text>
          </ListButton>
        </View>
      </TouchableWithoutFeedback>
    );
  }
}

const styles = {
  titleStyle: {
    alignSelf: 'center',
    color: '#fff',
    fontSize: 16,
    fontWeight: '600',
  }
};


const mapStateToProps = state => {
  //console.log('NAMES PRINT', names)
  return state
};  //this is lodash   .map iterates over key value pairs and run function which assigns data to groups array


export default connect(mapStateToProps)(ListName);
react-native react-navigation
4个回答
6
投票

基于React Navigation:https://reactnavigation.org/docs/en/connecting-navigation-prop.html

您只需将withNavigation导入子组件即可。

import { withNavigation } from 'react-navigation';

然后出口:

export default withNavigation(<YourChildComponent>);

4
投票

一种方法是在你的ProvideScreen组件中有一个onPress处理程序,它传递给你的列表项组件,因此在ProvideScreen的onRowPress函数中,你将有权访问this.props.navigation

ProvideScreen

class ProvideScreen extends Component {
  ...
  onRowPress(someRowData) {
    this.props.navigation.navigate('Feedback', { someRowData });
  }
  ...

  renderRow(user) {
    return <ListName name={user[0]} onRowPress={this.onRowPress} />;
  }
}

ListName

class ListName extends Component {
  ...
  onRowPress() {
    this.props.onRowPress(someData);
  }
  ...
}

当然,在使用事件处理程序时,不要忘记将函数绑定到this作用域。例如在构造函数中:

this.onRowPress = this.onRowPress.bind(this);

另一种用箭头函数定义onRowPress

onRowPress = () => {
 this.props.navigation.navigate...
}

2
投票

我只是从父母那里添加这个道具并且它有效:

<AppFooter navigation={this.props.navigation}  />

1
投票

传递所有道具

形成

{...this.props}

这里<Form>是我的孩子组成部分

除此以外。

import { withNavigation } from 'react-navigation';

然后到最后

export default withNavigation(<ChildComponentName>);

1
投票

您还可以通过执行以下操作直接将导航道具从父项传递给子项:

renderRow(user) {
    return <ListName name={user[0]} navigation={this.props.navigation}/>;
}

这将允许您在ListName中使用react-navigation的导航方法。

信息也来自此页面:https://reactnavigation.org/docs/en/connecting-navigation-prop.html


0
投票
import {withNavigation} from 'react-navigation';

class Parent extends Component{
  <Child {...this.props}/>
}

class Child extends Component {
  <TouchableOpacity onPress={()=>this.props.navigation.navigate("Screen")}>
    <V><T>
     {PRESS ME}
    </V></T>
  </TouchableOpacity>
}

export default withNavigation(Parent);
© www.soinside.com 2019 - 2024. All rights reserved.