从React Native

时间:2018-04-14 02:09:51

标签: reactjs react-native

我的React Js技能非常基础,我想要的是当我点击一个类别时,我会在新的屏幕中显示所选类别的帖子列表,在这种情况下是PostsScreen。

问题是我得到itemId null。

我不知道我做错了什么。

这些是我的屏幕和路线组件

类别屏幕

import React, {Component} from 'react';
import { NavigationActions, DrawerNavigator,  StackNavigator } from 'react-navigation';
import{Dimensions, Button, View, SafeAreaView, FlatList, ActivityIndicator, TouchableOpacity } from 'react-native';

export default class WGoals extends Component {
static navigationOptions = {
  title: 'Categories'
    };

navigateToScreen = (route, params) => () => {
const navigateAction = NavigationActions.navigate({
  routeName: route,
  params: params
});
this.props.navigation.dispatch(navigateAction);
}

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

  render() {

    return (

<Container style={styles.background_general}>
                <TouchableOpacity onPress={this.navigateToScreen('PostsScreen', itemId = '1')} >
                <Text>Category 1</Text>
            </TouchableOpacity>
                <TouchableOpacity onPress={this.navigateToScreen('PostsScreen', itemId = '2')} >
                <Text>Category 2</Text>
                </TouchableOpacity>
</Container>      
    );
  }
}

帖子屏幕

import React, {Component} from 'react';
import { NavigationActions, DrawerNavigator,  StackNavigator } from 'react-navigation';
import{Dimensions, View, SafeAreaView, FlatList, ActivityIndicator } from 'react-native';

export default class Posts extends Component {
static navigationOptions = {
  title: 'Posts'
};

  render() {

    const { params } = this.props.navigation.state;
    const itemId = params ? params.itemId : null;

    return (

<Container style={styles.background_general}>

<Text>Details Screen</Text>
<Text>itemId: {JSON.stringify(itemId)}</Text>

</Container>

    );
  }
    }

路线

import React from 'react';
import CategoriesScreen from '../screens/Categories';
import PostsScreen from '../screens/Posts';
import SideMenu from './SideMenu';
import {DrawerNavigator, StackNavigator} from 'react-navigation'

const navigationOptions = {
  navigationOptions: {
    headerStyle: {
      backgroundColor: '#f39c12',
    },
    headerTitleStyle: {
      textAlign: 'center',
      alignSelf: 'center',
      fontSize: 20,
      color: '#fff',
      fontWeight: 'bold'
    }
  }
};

const leftIcon = (navigation, icon) => <Icon
  name={icon}
  style={{marginLeft: 20}}
  size={20}
  color="white"
  onPress={() => navigation.navigate('DrawerOpen')}
/>;

const rightIcon = (navigation, icon) => <Icon
  name={icon}
  style={{marginLeft: 20}}
  size={30}
  color="white"
  onPress={() => navigation.navigate('CategoriesScreen')}
/>;

const CategoriesScreenStack = StackNavigator (
{
  Categories: {
    screen: CategoriesScreen,
    navigationOptions: ({navigation}) => ({
      drawerIcon: ({tintColor}) => (<Icon name="home" size={24} style={{color: '#f39c12'}} />),
      headerLeft: leftIcon(navigation, 'menu')
    })
  }
  },
  navigationOptions
);

const PostsScreenStack = StackNavigator(
  {
    PostsScreen: {
      screen: PostsScreen,
      navigationOptions: ({ navigation }) => ({
        drawerIcon: ({ tintColor }) => (<Icon name="user" size={24} style={{ color: tintColor }} />),
        headerLeft: leftIcon(navigation, 'menu')
      })
    }
  },
  navigationOptions
);

export default DrawerNavigator({
  CategoriesScreen: {
    screen: CategoriesScreenStack
  },
  PostsScreen: {
    screen: PostsScreenStack
      },
    }, {
  contentComponent: SideMenu,
  drawerWidth: width * .7,
  drawerOpenRoute: 'DrawerOpen',
  drawerCloseRoute: 'DrawerClose',
  drawerToggleRoute: 'DrawerToggle',
});

1 个答案:

答案 0 :(得分:0)

您希望将对象中的itemId传递给navigateToScreen,因为您正在访问params作为对象(params.itemId)中的WorkoutsGoalsList,目前尚未定义。

此外,onPress需要一个函数引用。就像现在一样,您实际上正在调用该函数,因此将在每次渲染时调用this.navigateGateToScreen。查看bind documentation,bind允许您创建具有特定参数列表的新函数:

render () {
  return (
    <Container style={styles.background_general}>
      <TouchableOpacity
        onPress={this.onPress.bind(this, '1')}
      >
        <Text>Category 1</Text>
      </TouchableOpacity>
      <TouchableOpacity
        onPress={this.onPress.bind(this, '2')}
      >
        <Text>Category 2</Text>
      </TouchableOpacity>
    </Container>
  );
};

onPress = (id) => {
  this.navigateToScreen('PostsScreen', { itemId: id })
};

您也无需顾问navigateToScreen功能:

navigateToScreen = (route, params) => {   // remove curry here
  const navigateAction = NavigationActions.navigate({
    routeName: route,
    params: params,
  });
  this.props.navigation.dispatch(navigateAction);
};

你的道具看起来像这样:

this.props = {
  navigation: {
    state: {
      params: {
        itemId: '1',
      }
    }
  }
};

在渲染中绑定不是最佳的,因为将在每次渲染调用时创建一个新函数。构建代码的更好方法是创建专用组件并传递itemIdonPress函数:

<强> WGoals

export default class WGoals extends Component {
  static navigationOptions = {
    title: 'Categories',
  };

  navigateToScreen = (route, params) => {
    const navigateAction = NavigationActions.navigate({
      routeName: route,
      params: params,
    });
    this.props.navigation.dispatch(navigateAction);
  };

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

  render() {
    return (
      <Container style={styles.background_general}>
        <Category name='Category1' onPress={this.navigateToScreen} itemId='1' />
        <Category name='Category2' onPress={this.navigateToScreen} itemId='2' />
      </Container>
    );
  }
}

<强>分类

export default class Category extends Component {
  render () {
    const { name } = this.props;

    return (
        <TouchableOpacity
          onPress={this.handlePress}
        >
          <Text>{name}</Text>
        </TouchableOpacity>
    );
  }

  handlePress = () => {
    const { itemId, onPress } = this.props;

    onPress('PostsScreen', { itemId: itemId });
  }
}

在PostsScreens中,您需要在字符串中呈现itemId,或者您可以通过将其包装在大括号({itemId})中来呈现变量的值。下面,我将其呈现为字符串并将itemId的值插入字符串中。查看template literal文档以获取有关语法的更多信息:

export default class Posts extends Component {
  static navigationOptions = {
    title: 'Posts',
  };

  render() {
    const { params } = this.props.navigation.state;
    const itemId = params ? params.itemId : null;

    return (
      <Container style={styles.background_general}>
        <Text>'Details Screen'</Text>
        <Text>`itemId: ${itemId}`</Text>
      </Container>
    );
  }
}