【问题标题】:How to load the same screen with a different parameter?如何使用不同的参数加载相同的屏幕?
【发布时间】:2019-01-30 12:59:08
【问题描述】:

我正在编写一个应用程序,这个应用程序只有一个屏幕,带有来自反应导航的抽屉。抽屉有一个类别列表,当我单击其中一个类别时,我希望使用新的类别参数“重新加载”屏幕。

我是这样称呼导航的:

<Drawer.Item
  label={category.name}
  key={category.id}
  active={global.activeCategory == category.id}
  onPress={() => {
    this.props.navigation.navigate('Home', {category: category.id});
    this.props.navigation.closeDrawer();
  }}
/>

它不起作用,但我不知道是因为我们无法在我们已经打开的屏幕上调用导航,还是因为屏幕已经被调用所以它不会再次触发我的 componentDidMount();

这是我用来获取内容的 componentDidMount:

async componentDidMount() {
  const paramCategory = this.props.navigation.getParam('category', 0);
  console.log(paramCategory);
  this.getJokes(this.state.category, 1); // category id + page number
};

我尝试使用 this.props.navigation.push('Home', {category: category.id});但我收到一个错误:“推送不是功能”。试图创建一个“中间人”屏幕以使用正确的参数重定向回主页。但它看起来很糟糕并且不会触发componentDidMount。我迷路了。

解决办法是什么?


这是我的肮脏肮脏的解决方案。它可以工作,但我不喜欢它。

在我的主屏幕中,我有一个强制重新渲染:

constructor(props) {
  super(props);

  this.forceRerender = this.props.navigation.addListener('willFocus', () => {
    this.getJokes(this.props.navigation.getParam('category', 0));
  });
}

componentWillUnmount() {
  this.forceRerender;
}

我创建了一个“中间人”,他还需要一个重新渲染,否则它只能工作一次:

class Middleman extends React.Component {

  componentDidMount() {
    const paramCategory = this.props.navigation.getParam('category', 0);
    this.props.navigation.navigate('Home', {category: paramCategory});
  };

  constructor(props) {
    super(props);

    this.forceRerender = this.props.navigation.addListener('willFocus', () => {
      const paramCategory = this.props.navigation.getParam('category', 0);
      this.props.navigation.navigate('Home', {category: paramCategory});
    });
  }

  componentWillUnmount() {
    this.forceRerender;
  }

  render() {
    return (<View></View>);
  }
}

【问题讨论】:

  • 我会用 nativebase 抽屉切换反应导航,并简单地使用 onPress 呈现类别以将活动类别设置为状态。
  • @Zayco,是的,对于这个项目,我可以。但我也对未来项目的解决方案感兴趣。例如,您在用户配置文件上,然后单击另一个用户,我也会遇到同样的问题。
  • 我添加了一个答案,应该以用户个人资料为例来解释这个概念

标签: react-native react-navigation


【解决方案1】:

我将使用您的用户配置文件示例作为基础,因为它更直接。

drawerNavigator 没有“堆叠”屏幕的能力。因此,您需要将屏幕包装在 stackNavigator 中。请注意,您必须使用 this.props.navigation.push() 才能将下一个屏幕添加到堆栈中。

I have provided a working snack example here

import React from 'react';
import { Button, View, Text, StyleSheet } from 'react-native';
import { createStackNavigator, createAppContainer, createDrawerNavigator } from 'react-navigation'; // Version can be specified in package.json

class UserScreen extends React.Component {

  renderListOfUsers = () => {
    const users = ['User 1', 'User 2', 'User 3'];

    return users.map(u => (
       <Button
          onPress={() => this.props.navigation.push('User', {userName: u})}
          title={`Go to ${u}`}
        />
    ));
  }; 

  render() {
    const userName = this.props.navigation.getParam('userName', 'none');

    return (
      <View style={{flex:1}}>
        <Button
          onPress={() => this.props.navigation.toggleDrawer()}
          title="Open Drawer"
        />
        <Text>Active user: {userName}</Text>

        {this.renderListOfUsers()}

      </View>
    );
  }
}

const UserStack = createStackNavigator({
  User: {
    screen: UserScreen
  }
})

const MyDrawerNavigator = createDrawerNavigator({
  User: {
    screen: UserStack,
  },
});

const MyApp = createAppContainer(MyDrawerNavigator);

export default MyApp;

【讨论】:

  • 你没有把链接放在抽屉里:snack.expo.io/@hotgeart/drawer-with-stack push 不起作用
  • 抽屉导航中不存在该功能。为了实现您所描述的,我真的认为最好的解决方案是使用像 nativebase 这样的普通 UI 库。看看snack.expo.io/@zayco/stack-with-nativebase-drawer
  • @Zayco 使用相同的示例是否可以 [ { label: 'Header title', children: [ { label: 'Sub-header title', children: [ { label: '3rd level #1 ' }, { label: '3rd level #2', children: [ { label: 'Level 4' } ] } ] } ] } ] 在每个页面中传递 children 数组?..你能帮帮我
【解决方案2】:

我将以下内容用于stacknavigator,idk如果它在抽屉导航器中工作,但你应该尝试

var Stack= createStackNavigator(
  {
    Main: {screen: ({ navigation }) => (<MainScreen navigation={navigation} value="Dogs" />)},
    Search:{screen: ({ navigation }) => (<Search navigation={navigation} value="Dogs" />)},
 Details:{screen: ({ navigation }) => (<Details navigation={navigation} value="Dogs" />)}
  },
  {
      // initialRouteName: 'Main',
    headerMode: 'none',

  }
);

在其他堆栈中,我有一个与猫,但屏幕相同。我只是用 this.props.value 访问值

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-06
    • 1970-01-01
    • 2020-04-23
    • 1970-01-01
    • 2017-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多