0

I have a conditional statement that determines which JSX should be rendered on screen. It looks at an array held in the state, and, if empty, renders an image and some text. However, if populated, the data is rendered using Flat List.

When the conditional statement equates to false (the array is empty) the image and text are rendered very briefly (for around half a second).

How can I alter it so it does not appear at all? As the logic would suggest.

My code is below:

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>
   );
 }
2
  • I assume you're waiting for data to be returned when it displays the first condition for a second. Perhaps you ought to have a loading screen until that's finished. Commented Apr 11, 2018 at 17:43
  • how do you populate this array? Commented Apr 12, 2018 at 11:16

2 Answers 2

1

Maybe your issue is related to your condition. You are checking for this.state.array and then for this.state.foods.

I rewrote some pieces of your code that may work as expected

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>
    );
 }

Just replace foods for array according to the correct prop declared in your state

This code will display the text Tap the (+)... when your array is empty.

So you don't want to display this text after all? If so, you can just change the condition to only render <FlatList> if your array exists and if it's length is > 0, something like:

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

If you want only to not display in the first render, then you might need a loading handler. Something like this:

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>
    );
 }

Hope it helps

Sign up to request clarification or add additional context in comments.

2 Comments

I had changed the code to arrary for the purpose of the question so it's not this unfortunately
I updated the answer, let me know if it solves your issue
0

As per MattyK14's recommendation, I included a spinner (or loading screen) that renders until the data is retrieved. This prevented the 'no data' screen from rendering very briefly before the list is returned.

This is included above the if statement:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.