【问题标题】:React Native: Conditional Render not working as it shouldReact Native:条件渲染无法正常工作
【发布时间】:2018-04-12 22:37:33
【问题描述】:

我有一个条件语句来确定应该在屏幕上呈现哪个 JSX。它查看状态中保存的数组,如果为空,则呈现图像和一些文本。但是,如果已填充,则使用平面列表呈现数据。

当条件语句等于 false(数组为空)时,图像和文本会非常短暂地呈现(大约半秒)。

我怎样才能改变它,使它根本不出现?正如逻辑所暗示的那样。

我的代码如下:

render() {
if (this.state.array === undefined || this.state.array.length === 0) {
  return (
    <View>
      <View>
        <Text> Tap the (+) button to add an item.</Text>
        <Image source={require('../images/image.png')} />
      </View>
    </View>
    );
}

//If array data
return (
    <View>
      <FlatList
          data={this.state.array}
          renderItem={({ item }) => <TrackedItem {...item} />}
          keyExtractor={(item, index) => index.toString()}
      />
    </View>
   );
 }

【问题讨论】:

  • 我假设您正在等待数据在显示第一个条件一秒钟时返回。也许你应该有一个加载屏幕,直到完成。
  • 你如何填充这个数组?

标签: javascript reactjs react-native


【解决方案1】:

也许您的问题与您的情况有关。您正在检查this.state.array,然后是this.state.foods

我重写了您的一些代码,它们可能会按预期工作

const { foods } = this.state;
render() {
  return (
    <View>
     {!foods || foods.length === 0 ?
      <View>
        <Text> Tap the (+) button to add an item.</Text>
        <Image source={require('../images/image.png')} />
      </View>
      :
      <FlatList
          data={foods}
          renderItem={({ item }) => <TrackedItem {...item} />}
          keyExtractor={(item, index) => index.toString()}
      />
     }
    </View>
    );
 }

只需根据您所在州声明的正确道具将foods替换为array

当您的数组为空时,此代码将显示文本 Tap the (+)...

所以你根本不想显示这个文本?如果是这样,您可以将条件更改为仅在您的数组存在且长度大于 0 的情况下呈现 &lt;FlatList&gt;,例如:

return (
    <View>
     {(foods && foods.length > 0) &&
      <FlatList
          data={foods}
          renderItem={({ item }) => <TrackedItem {...item} />}
          keyExtractor={(item, index) => index.toString()}
      />
     }
    </View>
  );

如果您只想在第一次渲染中不显示,那么您可能需要一个加载处理程序。像这样的:

state = {
  foods: [],
  loading: true,
}

async componentDidMount() {
  const yourArray = await getArrayValues(); // here you replace for whatever you use to fetch your data. Remember to use async/await, so you avoid triggering setState before the fetch is completed
  this.setState({
    foods: yourArray,
    loading: false,
  })
}

render() {
  const { foods, loading } = this.state;
  if (loading) return <ActivityIndicator />

  return (
    <View>
     {!foods || foods.length === 0 ?
      <View>
        <Text> Tap the (+) button to add an item.</Text>
        <Image source={require('../images/image.png')} />
      </View>
      :
      <FlatList
          data={foods}
          renderItem={({ item }) => <TrackedItem {...item} />}
          keyExtractor={(item, index) => index.toString()}
      />
     }
    </View>
    );
 }

希望对你有帮助

【讨论】:

  • 出于问题的目的,我已将代码更改为arrary,所以不幸的是不是这样
  • 我更新了答案,如果它解决了你的问题,请告诉我
【解决方案2】:

根据 MattyK14 的建议,我包含了一个微调器(或加载屏幕),它会在检索到数据之前呈现。这可以防止在返回列表之前非常短暂地呈现“无数据”屏幕。

这包含在 if 语句的上方:

  if (this.state.loading) {
  return <Spinner />;
}

【讨论】: