Плоский список с scrollTo в React Native

#react-native #expo #react-native-flatlist

#react-native #expo #react-native-плоский список

Вопрос:

Я новичок в React Native, я пытаюсь создать FlatList в приложении с Expo, которое будет извлекать некоторые категории продуктов из Json, мне удалось создать FlatList, а также имитацию Json для тестирования, однако я хотел бы, чтобы при нажатии на любой элемент в FlatList он перенаправлял прокрутку в соответствующий раздел, то же самое при использовании привязки с идентификатором в HTML.

Например: в FlatList будут отображаться категории: Комбинированные блюда, гарниры, хот-дог и т.д. Для каждой категории, отображаемой FlatList, я уже создал представление, в котором будут отображаться товары в этой категории.

Что я хочу сделать:

Когда вы нажимаете на категорию, отображаемую FlatList, прокрутка прокручивается до представления, в котором отображаются продукты этой категории, то есть, если вы нажимаете на Combo, страница прокручивается до представления, в котором отображаются продукты из категории Combo, если вы нажимаете на Гарниры, страница прокручивается до тех пор, пока представление, в котором отображаются продукты из категории гарниров, не будет следовать моему коду:

Следуйте моему коду: (его можно смоделировать здесь:https://snack.expo.io/@wendell_chrys/06944b)

 import React, { useEffect, useState } from 'react';
import { View, Image, ImageBackground, Text, StyleSheet, ScrollView, Dimensions, FlatList, SafeAreaView, TouchableOpacity } from 'react-native';
import { AppLoading } from 'expo';
import Constants from 'expo-constants';


const DATA = [
  {
    id: "1",
    title: "Combos",
    categorie: "section1",
  },
  {
    id: "2",
    title: "Side Dishes",
    categorie: "section2",
  },
  {
    id: "3",
    title: "Hot Dog",
    categorie: "section3",
  },
  {
    id: "4",
    title: "Desserts",
    categorie: "section4",
  },
  {
    id: "5",
    title: "Drinks",
    categorie: "section5",
  },
];

const renderItem = ({ item }) => {

  return (
    <Item
      item={item}
    />
  );
};

const Item = ({ item, onPress, style }) => (
  <TouchableOpacity onPress={onPress} >
    <Text style={styles.itenscategoria}>{item.title}</Text>
  </TouchableOpacity>
);



export default function App() {


  return (
    <View style={styles.container}>
      <View style={styles.categories}>

      <FlatList
        data={DATA}
        horizontal
        showsHorizontalScrollIndicator={false}
        renderItem={renderItem}
        keyExtractor={(item) => item.id}
      />


      </View>
        <ScrollView>
        <View style={styles.section1}>
          <Text>Combos</Text>
        </View>

        <View style={styles.section2}>
          <Text>Side Dishes</Text>
        </View>

        <View style={styles.section3}>
          <Text>Hot Dog</Text>
        </View>

        <View style={styles.section4}>
          <Text>Desserts</Text>
        </View>

        <View style={styles.section5}>
          <Text>Drinks</Text>
        </View>
      </ ScrollView>

    </View >
    );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#000',
    padding: 8,
  },
  categories: {
    backgroundColor: '#FFFFFF',
    width: '100%',
    height: 50,
    top: 10,
    marginBottom:20,
  },
  itenscategoria: {
    padding:15,
    border: 1,
    borderRadius:25,
    marginRight:10,
},
  section1: {
    marginTop: 10,
    backgroundColor: '#ccc',
    width: '100%',
    height: 200,
    borderRadius: 10,
  },
  section2: {
    marginTop: 10,
    backgroundColor: '#ccc',
    width: '100%',
    height: 200,
    borderRadius: 10,
  },
  section3: {
    marginTop: 10,
    backgroundColor: '#ccc',
    width: '100%',
    height: 200,
    borderRadius: 10,
  },
  section4: {
    marginTop: 10,
    backgroundColor: '#ccc',
    width: '100%',
    height: 200,
    borderRadius: 10,
  },
  section5: {
    marginTop: 10,
    backgroundColor: '#ccc',
    width: '100%',
    height: 200,
    borderRadius: 10,
  },
});
  

Ответ №1:

Вы можете использовать scrollToIndex из FlatList

Смотрите полный код ниже или закуску здесь.

 import React, { useEffect, useState, useRef } from 'react';
import { View, Image, ImageBackground, Text, StyleSheet, ScrollView, Dimensions, FlatList, SafeAreaView, TouchableOpacity } from 'react-native';
import { AppLoading } from 'expo';
import Constants from 'expo-constants';

const DATA = [
  {
    id: "1",
    title: "Combos",
    categorie: "section1",
  },
  {
    id: "2",
    title: "Side Dishes",
    categorie: "section2",
  },
  {
    id: "3",
    title: "Hot Dog",
    categorie: "section3",
  },
  {
    id: "4",
    title: "Desserts",
    categorie: "section4",
  },
  {
    id: "5",
    title: "Drinks",
    categorie: "section5",
  },
];

export default function App() {
  const flatListRef = useRef();
  
  const handleItemPress = (index) => {
    flatListRef.current.scrollToIndex({ animated: true, index });
  };

  const renderItem = ({ item, index }) => {
    return (
      <Item
        item={item}
        onPress={() => handleItemPress(index)}
      />
    );
  };

  const Item = ({ item, onPress, style }) => (
    <TouchableOpacity onPress={onPress} >
      <Text style={styles.itenscategoria}>{item.title}</Text>
    </TouchableOpacity>
  );

  const renderDetails = ({ item, index }) => (
    <View style={styles.section}>
      <Text>{item.title}</Text>
    </View>
  );

  return (
    <View style={styles.container}>
      <View style={styles.categories}>
        <FlatList
          data={DATA}
          horizontal
          showsHorizontalScrollIndicator={false}
          renderItem={renderItem}
          keyExtractor={(item) => item.id}
        />
      </View>
      <FlatList
        ref={flatListRef}
        data={DATA}
        renderItem={renderDetails}
        keyExtractor={(item) => item.id}
      />
    </View >
    );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#000',
    padding: 8,
  },
  categories: {
    backgroundColor: '#FFFFFF',
    width: '100%',
    height: 50,
    top: 10,
    marginBottom:20,
  },
  itenscategoria: {
    padding:15,
    border: 1,
    borderRadius:25,
    marginRight:10,
},
  section: {
    marginTop: 10,
    backgroundColor: '#ccc',
    width: '100%',
    height: 200,
    borderRadius: 10,
  },
});
  

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

1. Спасибо! Однако это не работает в веб-версии. Вы знаете, почему?