добавить условие в соответствии с наличием данных базы данных

#javascript #react-native #conditional-rendering

#javascript #react-native #условный-рендеринг

Вопрос:

У меня есть список, в который я хочу добавить изображение. В основном мой код работал нормально, и база данных API, которую я использую, к сожалению, изменилась… Некоторые продукты в моей базе данных не имеют изображения, поэтому при вызове соответствующей строки выдается сообщение об ошибке… Итак, я хочу создать условие: если в базе данных есть изображение для рассматриваемого продукта, я хочу, чтобы оно отображалось

Источник изображения={{uri: URL item.photo.1.url}}

В противном случае я хочу, чтобы это был предустановленный логотип. <Источник изображения={require(‘../../../assets/images/logo.png’)}

Я сделал это так:

  <ListItem.Content style={{flexDirection: 'row', justifyContent: 'space-between'}}>
                        {item.photo !== null amp;amp; item.photo > 0 ? (
                          <Image 
                            source={{uri: URL   item.photo._1_.url}}
                            style={{ width: 25, height: 25}}/> 
                        ) : (
                          <Image 
                            source={require('../../../assets/images/logo.png')}
                            style={{ width: 25, height: 25}}
                          />
                        )};
                        <ListItem.Title style={{width: '65%', fontSize: 16}}>{ ( item.name.length > 20 ) ? item.name.substring(0, 20)   ' ...'  :  item.name}</ListItem.Title>
                        <ListItem.Subtitle style={{ color: '#F78400', position: "absolute", bottom: 0, right: 0 }}>{item.cost}{i18n.t("products.money")}</ListItem.Subtitle>
                      </ListItem.Content>
 

Но у меня есть 2 ошибки:

неопределенный не является объектом (оценка ‘item.photo.1.url’)

[Отклонение необработанного обещания: ошибка: текстовые строки должны отображаться внутри компонента.]

Чтобы показать вам, как выглядят данные :

screendata

И полный код этого экрана :

 export default class Products extends Component {
  constructor(props) {
    super(props);
      this.state = {
        productId: (props.route.params amp;amp; props.route.params.productId ? props.route.params.productId : -1),
        listData: '',
        selectedId: '',
        setSelectedId: '',
        currentPage: 1,
        loadMoreVisible: true,
        loadMoreVisibleAtEnd: false,
        displayArray: []
      }
    };

  initListData = async () => {
    let list = await getProducts(1);
   
    if (list) {
      this.setState({
        displayArray: list,
        loadMoreVisible: (list.length >= 10 ? true : false), 
        currentPage: 2
      });
    }
  };

  setNewData = async (page) => {
    let list = await getProducts(parseInt(page));

    if (list) {
      this.setState({
        displayArray: this.state.displayArray.concat(list),
        loadMoreVisible: (list.length >= 10 ? true : false),
        loadMoreVisibleAtEnd: false,
        currentPage: parseInt(page) 1
      });
    }
  };

  loadMore() {
   this.setNewData(this.state.currentPage);
  }

  displayBtnLoadMore() {
    this.setState({
      loadMoreVisibleAtEnd: true
    });
  }

  async componentDidMount() {
    this.initListData();
  }

   render() {
  //console.log('url', URL );
  //console.log('displayArray', this.state.displayArray);
  //console.log('name', this.state.displayArray.name);
  //console.log('photo', this.state.displayArray.photo);
    return (
      <View style={{flex: 1}}>
        {this.state.displayArray !== null amp;amp; this.state.displayArray.length > 0 ? (
          <View style={{ flex: 1}}>
            <SafeAreaView>               
              <FlatList
                data={this.state.displayArray}
                extraData={this.selectedId}
                style={{width: '98%'}}
                onEndReached={() => this.displayBtnLoadMore()}
                renderItem={({item, index, separators })=>
                  <View style={{flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center'}}>
                    <ListItem
                      style={{width:'100%'}}
                      containerStyle= {{backgroundColor: index % 2 === 0 ? '#fde3a7' : '#FFF'}}
                      bottomDivider
                      onPress={() => this.props.navigation.navigate('ProductDetails', {productId:parseInt(item.id)})}>
                      <ListItem.Content style={{flexDirection: 'row', justifyContent: 'space-between'}}>
                        {item.photo !== null amp;amp; item.photo > 0 ? (
                          <Image 
                            source={{uri: URL   item.photo._1_.url}}
                            style={{ width: 25, height: 25}}/> 
                        ) : (
                          <Image 
                            source={require('../../../assets/images/logo.png')}
                            style={{ width: 25, height: 25}}
                          />
                        )};
                        <ListItem.Title style={{width: '65%', fontSize: 16}}>{ ( item.name.length > 20 ) ? item.name.substring(0, 20)   ' ...'  :  item.name}</ListItem.Title>
                        <ListItem.Subtitle style={{ color: '#F78400', position: "absolute", bottom: 0, right: 0 }}>{item.cost}{i18n.t("products.money")}</ListItem.Subtitle>
                      </ListItem.Content>
                    </ListItem>
                  </View>
                }
                keyExtractor={(item,index)=>index.toString()}
                style={{width:"100%"}}
              />
              {this.state.loadMoreVisible === true amp;amp; this.state.loadMoreVisibleAtEnd === true ? (
                  <Button title="   " onPress={()=>{this.loadMore()}}></Button>
                ) : null
              }
              <View style={styles.container}>
                <Text>{"n"}</Text>
                <TouchableOpacity
                  style={styles.touchable2}
                  onPress={() => this.props.navigation.goBack()}
                >
                  <View style={styles.container}>
                    <Button
                      color="#F78400"
                      title= 'Back'
                      onPress={() => this.props.navigation.goBack()}>BACK
                    </Button>
                  </View>
                </TouchableOpacity>
              </View>
              <Text>{"nn"}</Text>
            </SafeAreaView>
          </View>
        ) : (
          <View style={styles.container}>
            <Text>{"nn"   (this.state.displayArray === null ? i18n.t("products.searching") : i18n.t("products.nodata"))   "nnn"}</Text>
            <Button
              color="#F78400"
              title= 'Back'
              onPress={() => this.props.navigation.goBack()}>BACK
            </Button>
          </View>
        )}
      </View>
    );
  };
}
 

Я немного запутался в том, как это сделать, поэтому, если у вас есть какие-либо подсказки, чтобы помочь мне, любая подсказка, это было бы здорово. Большое спасибо

Ответ №1:

Этот тест:

item.photo !== null amp;amp; item.photo > 0

Не вернет то, что вы ожидаете. Причина в том, что когда нет фотографии, свойство устанавливается в пустую строку. Итак, первая часть этого теста должна быть:

item.photo !== ''

Далее, когда есть фотография, photo свойство является объектом. Итак, вторая часть должна быть:

item.photo.constructor === 'Object'

Но это будет усугубляться, если будет более одной фотографии. Ваш код предполагает, что вам нужна только первая фотография (независимо от того, сколько их может быть).

Поэтому, если вы внесете предложенные мной изменения, все должно работать так, как вы ожидаете.

На вашем месте я бы вообще пропустил первый тест, поскольку теперь в этом нет необходимости, поскольку второй тест охватывает оба случая. Я рекомендую просто сделать это:

{item.photo.constructor === 'Object' ? (

Комментарии:

1. Спасибо, и я понимаю ваши объяснения, спасибо, что нашли время разобраться и объяснить. Я тестирую и все еще получаю эту ошибку » [Отклонение необработанного обещания: ошибка: текстовые строки должны отображаться внутри компонента.] » Я не понимаю, я поставил условие не в том месте?

2. Я не вижу его здесь, но у вас где-то есть обычный текст в вашем возврате рендеринга. Я рекомендую вам удалить немного времени, чтобы посмотреть, сможете ли вы определить, где оно находится. Это может быть что-то столь же простое, как непечатаемый пробел (вы не можете видеть на экране). Но я ничего не вижу в этом коде.

3. Я думаю, что это мое первое условие, {this.state.displayArray !== null amp;amp; this.state.displayArray.length > 0 ? (……. Потому что, удалив его, он работает нормально… меня немного беспокоит его удаление, я включил его для безопасности, но, эй, может быть, я в конце концов удалю его, чтобы все было в порядке…

4. Ну, наконец, используя это: ‘{item.photo.constructor === ‘Object’ ? (‘ не сработало, но использование ‘ item.photo !== » ‘ само по себе работает нормально. Еще раз спасибо за вашу помощь. Я действительно благодарен