【问题标题】:Is there a better or more elegant way to conditionally render different components in React Native?有没有更好或更优雅的方式在 React Native 中有条件地渲染不同的组件?
【发布时间】:2021-01-31 11:31:04
【问题描述】:

我是 React Native 的新手,我正在尝试创建一个带有自定义导航栏的应用,当你点击链接时,它会在页面之间跳转。

这是我的代码的缩写版本:

class App extends Component {

  constructor(props) {
    super(props);
    this.state = {
      dicePage: true,
      itemsPage: false
    }
  }

  dicePress = () => {
        this.setState({
          dicePage: true,
          itemsPage: false
        })
  }
  itemsPress = () => {
        this.setState({
          dicePage: false,
          itemsPage: true
        })
  }

  render() {
    return (
      <View style={styles.container}>
        <ImageBackground source={backgroundTile} style={styles.bgImage}>
          <View style={styles.content}>
            <View style={styles.logoContainer}>
              <Image source={require('./assets/images/Logo.png')} style={styles.logo} />
            </View>
            {this.state.dicePage && <DicePage />}
            {this.state.itemsPage && <ItemsPage />}
            
            
            <NavBar value='Dice' dicePress={this.dicePress} itemsPress={this.itemsPress} />
          </View>
        </ImageBackground>
      </View>    
    );
  }
}

export default App;

class NavBar extends Component {
    constructor(props) {
        super(props);
    }
    render() {
        return (
            <View style={styles.bottomNav}>
                <TouchableOpacity onPress={this.props.dicePress}>
                    <Text key='dice' style={styles.nav}>Dice</Text>
                </TouchableOpacity>
                <TouchableOpacity onPress={this.props.itemsPress}>
                    <Text key='items' style={styles.nav}>Items</Text>
                </TouchableOpacity>
            </View>
        )
    }
}

export default NavBar;

所以这在我测试应用程序时有效 - 我将有 4 或 5 个页面,因此需要比三元运算符等更多的选项 - 但我认为可能有更好或更优雅的方法来做到这一点。

我已经尝试过 React Navigator 和其他东西,但我真的在寻找绝对简单的方法来实现这一点(希望使用 DRY 编码,因为重复对我来说感觉不对)。我应该为此映射链接函数吗?我认为我以前从未映射过函数,并意识到可能应该有一个适用于所有人的自适应函数。

感谢您的建议!

【问题讨论】:

    标签: reactjs react-native navigation


    【解决方案1】:

    第一种方法

    您可以创建一个pages 对象,其中每个键是页面的标识符,每个对应的值是代表页面的组件:

    const pages = {
      dicePage: DicePage,
      itemsPage: ItemsPage
    };
    

    这样我们可以只根据键来决定应该渲染什么,并且所有导航可以链接可以共享相同的onPress处理程序。

    App.js

    class App extends Component {
      constructor(props) {
        super(props);
        this.state = {
          currentPage: "dicePage" // Default page
        };
      }
    
      pagePress = (pageName) => {
        this.setState({ currentPage: pageName });
      };
    
      render() {
        const Page = pages[this.state.currentPage]; // What page should be rendered (based on the `currentPage` key)
        return (
          <View>
            <View>
              <Page />
              <NavBar value="Dice" pagePress={this.pagePress} />
            </View>
          </View>
        );
      }
    }
    

    Navbar.js

    class NavBar extends Component {
      render() {
        return (
          <View>
            <TouchableOpacity onPress={() => this.props.pagePress("dicePage")}>
              <Text key="dice">Dice</Text>
            </TouchableOpacity>
            <TouchableOpacity onPress={() => this.props.pagePress("itemsPage")}>
              <Text key="items">Items</Text>
            </TouchableOpacity>
          </View>
        );
      }
    }
    

    因此,如果您想用更多页面扩展它,您只需将键值对添加到pages 对象并链接到您的Navbar

    为了简化示例,我删除了样式和图像等一些内容。

    第二种方法

    const pages = [
      { key: "dicePage", page: DicePage, pageLinkName: "Dice" },
      { key: "itemsPage", page: ItemsPage, pageLinkName: "Items" },
    ];
    
    class NavBar extends Component {
      render() {
        return (
          <View>
            {pages.map((page) => {
              return (
                <TouchableOpacity
                  onPress={() => this.props.pagePress(page.key)}
                  key={page.key}
                >
                  <Text>{page.pageLinkName}</Text>
                </TouchableOpacity>
              );
            })}
          </View>
        );
      }
    }
    
    class App extends Component {
      constructor(props) {
        super(props);
        this.state = {
          currentPage: "dicePage", // Default page
        };
      }
    
      pagePress = (pageName) => {
        this.setState({ currentPage: pageName });
      };
    
      render() {
        const Page = pages.filter((page) => page.key === this.state.currentPage)[0]
          .page;
        return (
          <View>
            <View>
              <Page />
              <NavBar value="Dice" pagePress={this.pagePress} />
            </View>
          </View>
        );
      }
    }
    

    大致相同的方法,但pages 的结构发生了变化,您现在也不需要手动添加新链接,而只需将新对象添加到pages,它现在是一个数组。

    【讨论】:

      猜你喜欢
      • 2018-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-11
      • 1970-01-01
      • 2019-01-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多