有没有更好或更优雅的方式在 React Native 中有条件地渲染不同的组件? [英] Is there a better or more elegant way to conditionally render different components in React Native?

查看:58
本文介绍了有没有更好或更优雅的方式在 React Native 中有条件地渲染不同的组件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm new to React Native and I'm trying to create an app with a custom navbar, that jumps between pages when you click links.

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

Here is an abbreviated version of my code:

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 页,所以想要比三元运算符等更多的选项 - 但我认为可能有更好或更优雅的方法来做到这一点.

So this works when I test the app - and I'm going to have 4 or 5 pages, so want more options than a ternary operator etc. - but I think there's probably a better or more elegant way to do this.

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

I've tried React Navigator and other things but am really looking for the absolute simplest way to achieve this (hopefully with DRY coding, as the repetition feels wrong to me). Should I be mapping links and functions for this? I don't think I've ever mapped functions before and realise that there probably should be a single adaptable function that would work for all.

感谢您的建议!

推荐答案

第一种方法

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

First Approach

You could make a pages object where each key is an identifier for a page and where each corresponding value is the component that represents a page:

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

通过这种方式,我们可以仅根据键来决定应该呈现什么,并且所有导航可以链接可以共享相同的 onPress 处理程序.

This way we can decide what should be rendered based on the key only, and all navigation can links can share the same onPress handler.

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.

So if you want to expand this with more pages you only need to add key value pairs to the pages object and links to your 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添加新对象code>,现在是一个数组.

Largely the same approach, but structure of pages has changed where you now also don't need to manually add new links, but you only need to add new objects to pages, which is now an array.

这篇关于有没有更好或更优雅的方式在 React Native 中有条件地渲染不同的组件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆