在react或react-native中处理渲染函数中的多个返回的正确方法是什么

时间:2019-05-24 04:39:03

标签: javascript reactjs react-native expo

我使用expo在本机中具有以下组成部分:

import React, { Component } from 'react';
import { Text, View, ActivityIndicator } from 'react-native';
import { Location, Permissions } from 'expo';

export default class WeatherReport extends Component {

  state = {
    grantedLocationPermission: '',
    location: null,
  }

  componentDidMount() {
    Location.requestPermissionsAsync();
    Permissions.getAsync(Permissions.LOCATION)
      .then(({ status }) => {
        this.setState({
          grantedLocationPermission: status,
        })
      })
      .catch((error) => {
        console.warn(error);
        this.setState({
          grantedLocationPermission: 'undetermined'
        })
      })
  }

  render() {
    if(this.state.grantedLocationPermission === 'granted') {
      return (
        <View>
        <Text>Welcome to Weatheru!</Text>
        </View>
      )
    } else if(this.state.grantedLocationPermission === 'denied' || this.state.grantedLocationPermission === 'undetermined') {
      return (
        <View>
          <Text>Permission denied!</Text>
        </View>
      )
    } else {
      return (
        <View>
          <ActivityIndicator size={100} color="#5D50FE" />
        </View>
      )
    }
  }
}

render()中有三个返回值,其中两个返回了this.state.grantedLocationPermission特定值的视图。但是,当此组件首先加载this.state.grantedLocationPermission = ''时,然后将其重新呈现为特定值。结果,我使用了ActivityIndicator(简单加载程序)来显示所有其他情况下的加载动画。

这是正确的方法吗?还是有更好的方法?

1 个答案:

答案 0 :(得分:2)

您可以创建状态到组件的映射,还可以创建默认/后备处理程序。像这样:

const Denied = () => <Text>Permission Denied!</Text>;
const DefaultHandler = () => <ActivityIndicator size={100} color="#5D50FE" />;

const handlers = {
  granted: () => <Text>Welcome to Weatheru!</Text>,
  denied: Denied,
  undetermined: Denied,
}

const Cmp = handlers[this.state.grantedLocationPermission] || DefaultHandler;

return (
  <View>
    <Cmp />
  </View>
);

您所做的没有什么错误。可以。

但是应用一些通用的编程最佳实践将以多种方式提高可读性和可维护性。

为每种情况建立一个单独的组件,更紧密地遵循single responsibility principle

  1. 大大降低了WeatherReport组件的render方法的复杂性,使其更易于阅读和推理。

  2. 无需为每种情况重复使用<View>容器。如果您决定更换容器,则只需要在一个地方进行即可。 ({don't repeat yourself,避免使用duplicate code等)

  3. 使您可以单独更改每种情况的行为或输出,而不必在WeatherReport的render方法中进行一堆条件渲染逻辑。这些组件中的每一个都可以移至其自己的单独文件中,以供重复使用和/或实现更复杂的行为而不会污染WeatherReport组件。

    假设您需要显示“权限被拒绝!”在整个应用中的许多地方,然后您决定需要将其更改为“未经授权!”或者您需要多语种支持,并且需要说“祖康Verweigert!”针对特定的语言环境。如果您只有一个组件可以在您的应用程序需要的任何地方呈现它,则修改该组件可以在任何地方修复它。

  4. 使将来更容易支持其他状态。假设您的权限变得比授予/拒绝的权限更详细;也许您具有管理功能,或者只允许查看报告的特定部分。添加admin: AdministratorViewrestricted: RestrictedView非常简单,根本不会使基本组件的渲染逻辑复杂化。

再次,从功能上讲,这是相同的事情,但是如果您的应用要变得最复杂,就需要事先考虑这些事情并相应地进行编码。