jjzjj

javascript - 导航实验正在卸载选项卡

coder 2024-05-16 原文

我正在开发一个使用复合实验导航(CardStack + 选项卡)和 redux 进行状态管理的 React native 应用程序。我能够创建基于选项卡的导航,但我现在面临的问题是当我在选项卡之间切换时,组件被卸载并且每次都重新呈现。

问题

假设我向下滚动了几篇文章,当我更改 Tab 时,它将从顶部开始。 (解决方法可能是将滚动位置存储在 redux 状态中)。

这是我用于导航的示例代码 Tabbed Experimental Navigation

最佳答案

您必须更改 TabBar 的方法。

基本上,您希望每个选项卡都有一个导航器,因此您可以为每个选项卡设置路由堆栈,并使用一个导航器来包含选项卡 (TabBar)。您还想为 TabBar 设置初始路由堆栈并在这些路由之间跳转。

了解导航器方法之间的区别很重要。

  • 当您pop 路由时,它被卸载,事件索引被移动到 最后一个。由于最后一个保持状态,它将恢复原样 以前渲染过(很可能,它可能发生 Prop 改变)。再次转到 popped 路线将完全重新渲染场景(这发生在你身上)。

  • 当您push 路由时,没有卸载任何东西,新路由被挂载。

  • 当您jumpToIndex 路由时,再次没有卸载,因此跳转
    路线之间恢复原样的场景(同样,如果 Prop 改变 场景将被重新渲染)。

所以,我认为这是不正确的:

I was able to create Tab based Navigation but the issue that i am facing now is when i switch between tabs the component is unmounted and it re-render every time.

...您使用错误的导航操作卸载了路由。

现在还有什么不同,NavigationCardStack 不会实际创建它自己的状态,它是从外部传递的,这为您提供了极大的灵 active 。还有一件好事是,您可以使用 Facebook 提供的缩减程序来执行常见操作(例如推送、弹出、跳转到索引;它们是导航实用程序的一部分)。

您有关于如何创建 navigationState 及其缩减器的完整示例 here ,所以我不打算对此进行解释,只是想说明如何解决您的问题。

[更新] 示例现在可用!

import React from 'react';
import { NavigationExperimental, View, Text, StyleSheet } from 'react-native';

const {
  CardStack: NavigationCardStack,
  StateUtils: NavigationStateUtils,
} = NavigationExperimental;

const style = StyleSheet.create({
  screen: {
    flex: 1,
  },
  screenTitle: {
    marginTop: 50,
    fontSize: 18,
  },
  pushNewScreenLabel: {
    marginVertical: 10,
    fontSize: 15,
    fontWeight: "bold",
  },
  goBackLabel: {
    fontSize: 15,
  },
  tabBarWrapper: {
    position: 'absolute',
    height: 50,
    bottom: 0,
    left: 0,
    right: 0,
    top: null,
    backgroundColor: 'grey',
    flexDirection: 'row',
    flex: 0,
    alignItems: 'stretch',
  },
  tabBarItem: {
    flex: 1,
    justifyContent: 'center',
    backgroundColor: 'red',
  },
});

export class TabBar extends React.Component {
  constructor(props, context) {
    super(props, context);

    this.jumpToTab = this.jumpToTab.bind(this);

    // Create state
    this.state = {
      navigationState: {
        // Active route, will  be rendered as default
        index: 0,
        // "tab-s" represents route objects
        routes: [
          { name: 'Tab1', key: '1' },
          { name: 'Tab2', key: '2' },
          { name: 'Tab3', key: '3' },
          { name: 'Tab4', key: '4' }],
      },
    };
  }

  jumpToTab(tabIndex) {
    const navigationState = NavigationStateUtils.jumpToIndex(this.state.navigationState, tabIndex);
    this.setState({ navigationState });
  }

  renderScene({ scene }) {
    return <Tab tab={scene.route} />;
  }

  render() {
    const { navigationState } = this.state;
    return (
      <View style={style.screen}>
        <NavigationCardStack
          onNavigate={() => {}}
          navigationState={navigationState}
          renderScene={this.renderScene}
        />
        <View style={style.tabBarWrapper}>
          {navigationState.routes.map((route, index) => (
            <TabBarItem
              key={index}
              onPress={this.jumpToTab}
              title={route.name}
              index={index}
            />
            ))}
        </View>
      </View>
    );
  }
}

class TabBarItem extends React.Component {
  static propTypes = {
    title: React.PropTypes.string,
    onPress: React.PropTypes.func,
    index: React.PropTypes.number,
  }

  constructor(props, context) {
    super(props, context);
    this.onPress = this.onPress.bind(this);
  }
  onPress() {
    this.props.onPress(this.props.index);
  }
  render() {
    return (
      <Text style={style.tabBarItem} onPress={this.onPress}>
        {this.props.title}
      </Text>);
  }
}

class Tab extends React.Component {
  static propTypes = {
    tab: React.PropTypes.object,
  }

  constructor(props, context) {
    super(props, context);
    this.goBack = this.goBack.bind(this);
    this.pushRoute = this.pushRoute.bind(this);
    this.renderScene = this.renderScene.bind(this);
    this.state = {
      navigationState: {
        index: 0,
        routes: [{ key: '0' }],
      },
    };
  }

  // As in TabBar use NavigationUtils for this 2 methods
  goBack() {
    const navigationState = NavigationStateUtils.pop(this.state.navigationState);
    this.setState({ navigationState });
  }

  pushRoute(route) {
    const navigationState = NavigationStateUtils.push(this.state.navigationState, route);
    this.setState({ navigationState });
  }

  renderScene({ scene }) {
    return (
      <Screen
        goBack={this.goBack}
        goTo={this.pushRoute}
        tab={this.props.tab}
        screenKey={scene.route.key}
      />
    );
  }

  render() {
    return (
      <NavigationCardStack
        onNavigate={() => {}}
        navigationState={this.state.navigationState}
        renderScene={this.renderScene}
      />
    );
  }
}

class Screen extends React.Component {
  static propTypes = {
    goTo: React.PropTypes.func,
    goBack: React.PropTypes.func,
    screenKey: React.PropTypes.string,
    tab: React.PropTypes.object,
  }

  constructor(props, context) {
    super(props, context);
    this.nextScreen = this.nextScreen.bind(this);
  }

  nextScreen() {
    const { goTo, screenKey } = this.props;
    goTo({ key: `${parseInt(screenKey) + 1}` });
  }

  render() {
    const { tab, goBack, screenKey } = this.props;
    return (
      <View style={style.screen}>
        <Text style={style.screenTitle}>
          {`Tab ${tab.key} - Screen ${screenKey}`}
        </Text>
        <Text style={style.pushNewScreenLabel} onPress={this.nextScreen}>
          Push Screen into this Tab
        </Text>
        <Text style={style.goBackLabel} onPress={goBack}>
          Go back
        </Text>
      </View>
    );
  }
}
## 待定更多清理..

关于javascript - 导航实验正在卸载选项卡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39007521/

有关javascript - 导航实验正在卸载选项卡的更多相关文章

  1. ruby - 默认情况下使选项为 false - 2

    这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb

  2. ruby-on-rails - 使用 config.threadsafe 时从 lib/加载模块/类的正确方法是什么!选项? - 2

    我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co

  3. ruby - 在不使用 RVM 的情况下在 Mac 上卸载和升级 Ruby - 2

    我最近决定从我的系统中卸载RVM。在thispage提出的一些论点说服我:实际上,我的决定是,我根本不想担心Ruby的多个版本。我只想使用1.9.2-p290版本而不用担心其他任何事情。但是,当我在我的Mac上运行ruby--version时,它告诉我我的版本是1.8.7。我四处寻找如何简单地从我的Mac上卸载这个Ruby,但奇怪的是我没有找到任何东西。似乎唯一想卸载Ruby的人运行linux,而使用Mac的每个人都推荐RVM。如何从我的Mac上卸载Ruby1.8.7?我想升级到1.9.2-p290版本,并且我希望我的系统上只有一个版本。 最佳答案

  4. ruby - 我正在学习编程并选择了 Ruby。我应该升级到 Ruby 1.9 吗? - 2

    我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or

  5. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  6. Ruby on Rails regexp equals-tilde 与 array include 用于检查选项列表 - 2

    我正在使用Rails3.2.3和Ruby1.9.3p0。我发现我经常需要确定某个字符串是否出现在选项列表中。看来我可以使用Ruby数组.includemethod:或正则表达式equals-tildematchshorthand用竖线分隔选项:就性能而言,一个比另一个好吗?还有更好的方法吗? 最佳答案 总结:Array#include?包含String元素,在接受和拒绝输入时均胜出,对于您的示例只有三个可接受的值。对于要检查的更大的集合,看起来Set#include?和String元素可能会获胜。如何测试我们应该根据经验对此进行测试

  7. ruby - 如何测试正在使用 RSpec 和 Mocha 调用的混合类方法? - 2

    我有一个模块:moduleMyModuledefdo_something#...endend由类使用如下:classMyCommandextendMyModuledefself.execute#...do_somethingendend如何验证MyCommand.execute调用了do_something?我已经尝试使用mocha进行部分模拟,但是当未调用do_something时它不会失败:it"callsdo_something"doMyCommand.stubs(:do_something)MyCommand.executeend 最佳答案

  8. ruby - 选项卡的 Rubocop - 2

    我们想使用Rubocop来验证我们的ruby​​在语法上是否正确并遵循基本代码指南。除此之外我们有这个规则:我们使用制表符缩进以允许任何人决定他们希望如何呈现它们(将它们显示为2或4个空格)问题是rubocop似乎设计为完全拒绝缩进标签。我们怎样才能超越所有这些规则成为太空合规者?编辑:我正在考虑覆盖这个模块https://github.com/bbatsov/rubocop/blob/master/lib/rubocop/source_parser.rb将我文件中的所有制表符替换为2个空格,以创建gem的幻觉... 最佳答案 添加

  9. ruby - Ruby 中的选项菜单 - 2

    我正在尝试在Ruby中创建一个菜单,以便根据用户输入的内容,取决于调用的类。然后在这种情况下它将返回到“Main”或类“Options”。我希望有人能帮助我。这是我的代码。modulePhysicsG=21C=20000Pi=3.14D=100endclassOptionsputs"Pleaseselect1forAccelerationand2forEnergy."option=gets()ifoption==1thenputs"AccelCalc"#ThisisthebitthatneedstodirecttheusertotheclassAccelCalcelseputs"Ene

  10. ruby - 在 Mechanize 中使用 JavaScript 单击链接 - 2

    我有这个:AccountSummary我想单击该链接,但在使用link_to时出现错误。我试过:bot.click(page.link_with(:href=>/menu_home/))bot.click(page.link_with(:class=>'top_level_active'))bot.click(page.link_with(:href=>/AccountSummary/))我得到的错误是:NoMethodError:nil:NilClass的未定义方法“[]” 最佳答案 那是一个javascript链接。Mechan

随机推荐