【问题标题】:Can't render based on this.state in React Native无法在 React Native 中基于 this.state 进行渲染
【发布时间】:2015-10-26 04:58:54
【问题描述】:

知道为什么{this.state.showTabBar === true ? this._renderTabBar : null}SampleApp 组件中失败了吗?如果只渲染<TabBarExample />,效果很好。

我的目标是使用this.state.showTabBar 来决定何时显示 TabBarIOS。

这是一个 React Native Playground 链接: https://rnplay.org/apps/5pQC9A

'use strict';

var React = require('react-native');
var {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  TabBarIOS,
  TouchableHighlight,
} = React;


var SampleApp = React.createClass({
  getInitialState: function() {
    return {
      showTabBar: true // I will eventually use this to decide 
                                        // if TabBarIOS will be visible.
    };
  },

  _renderTabBar: function() {
    return (
        <TabBarExample />
    );
  },

  render: function() {    
    return (         
      // This line fails.
      {this.state.showTabBar === true ? this._renderTabBar : null}

        // <TabBarExample /> // This will work if uncomment.
    );
  }
});


var TabBarExample = React.createClass({
  statics: {
    title: '<TabBarIOS>',
    description: 'Tab-based navigation.',
  },

  displayName: 'TabBarExample',

  getInitialState: function() {
    return {
      selectedTab: 'blueTab',
      notifCount: 0,
      presses: 0,
    };
  },

  _renderContent: function(color: string, pageText: string, num?: number) {
    return (
      <View style={[styles.tabContent, {backgroundColor: color}]}>
        <Text style={styles.tabText}>{pageText}</Text>
        <Text style={styles.tabText}>{num} re-renders of the {pageText}</Text>
      </View>
    );
  },

  render: function() {
    return (
      <TabBarIOS
        tintColor="white"
        barTintColor="darkslateblue"
          translucent={true}>

        <TabBarIOS.Item
          title="Blue Tab"
          systemIcon="search"
          selected={this.state.selectedTab === 'blueTab'}
          onPress={() => {
            this.setState({
              selectedTab: 'blueTab',
            });
          }}>
          <MyViewOne />
        </TabBarIOS.Item>

        <TabBarIOS.Item
          title="Red Tab"
          systemIcon="history"
          badge={this.state.notifCount > 0 ? this.state.notifCount : undefined}
          selected={this.state.selectedTab === 'redTab'}
          onPress={() => {
            this.setState({
              selectedTab: 'redTab',
              notifCount: this.state.notifCount + 1,
            });
          }}>
          {this._renderContent('#783E33', 'Red Tab', this.state.notifCount)}
        </TabBarIOS.Item>

        <TabBarIOS.Item
          systemIcon="contacts"
          title="More Green"
          selected={this.state.selectedTab === 'greenTab'}
          onPress={() => {
            this.setState({
              selectedTab: 'greenTab',
              presses: this.state.presses + 1
            });
          }}>
          {this._renderContent('#21551C', 'Green Tab', this.state.presses)}
        </TabBarIOS.Item>

      </TabBarIOS>
    );
  }
});


var MyViewOne = React.createClass({
  render: function() {
    return (            
      <View style={[styles.tabContent, {backgroundColor: 'orange'}]}>
        <Text style={styles.tabText}>I like Iron Maiden</Text>
      </View>
    );
  }
});


var styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  tabContent: {
    flex: 1,
    alignItems: 'center',
  },
  tabText: {
    color: 'white',
    margin: 50,
  },  
  button: {
    backgroundColor: 'green',
    margin: 10,
  }  
});

AppRegistry.registerComponent('SampleApp', () => SampleApp);

【问题讨论】:

  • 这里的“失败”到底是什么意思?你有错误吗?或者不是你期望的结果?请更准确。
  • 我无法打开您的游乐场链接,但看起来您实际上并未调用 _renderTabBar 方法。你需要这样称呼它。_renderTabBar()
  • 谢谢,我起得太晚了,错过了。 React Native 中的错误消息对我没有帮助,它只是在“this.state.showTabBar”周围的列中显示语法错误,这让我陷入了循环。
  • @GorkemYurtseven 我在日常工作中遇到了同样的问题,www.rnplay.org 网站被我们的防火墙阻止了。关于用()正确调用func,还是不行。

标签: reactjs react-native


【解决方案1】:

就像 Gortem 所说,您没有调用该函数。 React 不会为你做这件事。

另外,你可以这样做:

{this.state.showTabBar && this._renderTabBar()}

或直接:

{this.state.showTabBar && (<TabBarExample />)}

【讨论】:

  • 您的 && 示例是非常糟糕的编码风格恕我直言。
  • @GiantElk 哇……想详细说明一下吗?如果您认为仅用于一种条件的三元组是“好”,我想我的例子是“坏”是的。
  • 这太难读了,在你的代码中,它看起来像:如果 this.state.showTabBar === true 那么你得到 {true && ()},它转换为{true && true} 即 {true}。至少在我看来是这样。使用显式 if then else 或三元运算符很明显,不需要思考。
【解决方案2】:

我认为你应该让 showTabBar 成为你的状态之一:

getInitialState: function(){
  return{
    showTabBar: {false}
  };
}

并使用

this.setState({showTabBar:{true}});

更新

【讨论】:

  • 是的,正确,但首先我需要让基本渲染工作。
【解决方案3】:

你应该在 return 语句之外有你的逻辑,如下所示:

render: function() {
  if (this.state.showTabBar) {
    return (this._renderTabBar());
  } else {
    return (<View />);
  }
}

还需要注意的是,您总是需要返回一个组件,即使它是一个空白视图。

下面是工作示例:https://rnplay.org/apps/-TjJ7w

【讨论】:

  • 不,逻辑驻留在哪里,在单独的函数对象中,或者如您显示的那样内联都没有关系。在 this._renderTabBar 之后我错过了 ()。试图在深夜远离时编码的结果。
  • 这真的让我很困惑,知道为什么这不起作用。类似的代码在 ReactJS rnplay.org/apps/8LmYhQ 中运行良好
  • 如何在渲染中只使用 1 个返回语句来编写这个?更简洁的代码 IMO 每个函数/方法只有 1 个返回值。
  • 谢谢。那是我第一次看到带有 标签的渲染中使用的 var。我总是将它放在 ReactJS 网络应用的 {} 中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-28
  • 1970-01-01
相关资源
最近更新 更多