Следует ли добавлять данные в flatlist или заменять данные в flatlist (рекомендации для тяжелых компонентов в flatlist)?

#javascript #reactjs #react-native #react-hooks #react-native-flatlist

#javascript #reactjs #react-native #реагирующие хуки #react-native-flatlist

Вопрос:

Я использую react-native-socials для отображения данных tweet из серверного API в flatlist. Я реализовал PullToRefresh, а также обновил ленту, когда мы дойдем до конца.

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

Я использую useState для настройки канала, и это перезагружает flatlist.

В настоящее время я заменяю канал новыми данными.

Проблема

После того, как несколько раз поток обновляется из серверной pullToRefresh части, я получаю undefined in this Twitter элемент из библиотеки.

TweetImage

Вот код для feed page :

 ~~~ SNIP Imports ~~~
function FeedScreen({ navigation, route, typeOfFeed }) {
    const typeOfFeed = 1;
    const { user, setUser } = useContext(AuthContext);
    const [tcursor, settCursor] = useState({
      previous: "",
      next: "",
    });
    const [feed, setFeed] = useState([]);
    const [refreshing, setRefreshing] = useState(false);
    const refContainer = useRef(null);
    const showToast = (message) => {
      ToastAndroid.show(message, ToastAndroid.SHORT);
    };

    useEffect(() => {
      loadFeed(typeOfFeed);
    }, []);
  
    const loadFeed = async (typeOfFeed, old = false) => {
      setRefreshing(true);
      let userData = await getAndRefreshToken();
      if (userData) {
        setUser(userData);
      }
      postsApi.setAuthToken(userData["idToken"]["jwtToken"]);
      let url = tcursor.next;

      const deDupeIt = (...arrs) => [...new Set([].concat(...arrs))];
      const response = await postsApi.getPosts(typeOfFeed, url);
      if (response.ok) {
        if (response.data[0].id == feed[0]?.id) {
          ToastAndroid.show("No new posts", ToastAndroid.SHORT);
        } else if (response.data.length > 0) {
          // This code is for adding a fixed length of array elements
          //
          // let oldLength = feed.length;
          // const feedNew = deDupeIt(feed, response.data);
          // if (feedNew.length <= oldLength) {
          //   oldLength = 0;
          // }
          // const feed100 = feedNew.slice(Math.max(feedNew.length - oldLength, 0));
          //
        settCursor({
            next: response.headers.next,
            previous: response.headers.previous,
        });
          setFeed(response.data);
        }
      } else {
        ToastAndroid.show("No new posts", ToastAndroid.SHORT);
        console.error(response.problem);
      }
      setRefreshing(false);
    };
    return (
        <Screen style={styles.screen}>
          {feed.length != 0 ? (
            <PostFlatlist
              refContainer={refContainer}
              feed={feed}
              onRefresh={() => {
                loadFeed(typeOfFeed);
              }}
              refreshing={refreshing}
              handleBookmark={handleBookmark}
              onEndReached={() => {
                if (refContainer.current) {
                  refContainer.current.scrollToIndex({ animated: true, index: 0 });
                }
                loadFeed(typeOfFeed, true);
              }}
              onEndReachedThreshold={0.01}
            />
          ) : (
            <View
              style={{
                height: "100%",
                width: "100%",
                justifyContent: "center",
                alignItems: "center",
              }}
            >
              {refreshing ? (
                <ActivityIndicator size="large" color={colors.twitterBlue} />
              ) : (
                <TouchableOpacity
                  onPress={() => {
                    loadFeed(typeOfFeed);
                  }}
                  style={styles.appButtonContainer}
                >
                  <MaterialCommunityIcons name="reload" size={30} color="black" />
                  <Text style={styles.appButtonText}>Reload Feed</Text>
                </TouchableOpacity>
              )}
            </View>
          )}
        </Screen>
      );
    }
  

Код для PostFlatlist.js

 ~~~ SNIP Imports ~~~

const renderItem = ({ item }) => (
  <View
    style={{
      padding: 10,
      borderRadius: 35,
      backgroundColor: colors.white,
    }}
  >
    {item.type == postType.TWEET amp;amp; (
      <Twitter useCustomTweetExtendedData={item.content} />
    )}
  </View>
);

function PostFlatlist({
  feed,
  style,
  refreshing,
  onRefresh,
  handleBookmark,
  ListHeaderComponent,
  onEndReached,
  onEndReachedThreshold,
  refContainer,
}) {
  return (
    <FlatList
      ref={refContainer}
      data={feed}
      keyExtractor={(post) => {
        return post.id.toString();
      }}
      ListHeaderComponent={ListHeaderComponent}
      renderItem={renderItem}
      ItemSeparatorComponent={ListItemSeparator}
      refreshing={refreshing}
      onRefresh={onRefresh}
      onEndReached={onEndReached}
      onEndReachedThreshold={onEndReachedThreshold}
    />
  );
}

export default PostFlatlist;
  

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

1. Можете ли вы уточнить или расширить, что на самом деле означает «После нескольких загрузок фида я получаю неопределенный в этом элементе Twitter из библиотеки»? Что не определено? Какой элемент Twitter? Из какой библиотеки? Есть ли ошибка?

2. @DrewReese извините, что написал это случайно. Обновлено с добавлением большего контекста. Спасибо, что изучили это. Я упомянул библиотеку, и элемент twitter взят из самой этой библиотеки.

3. Из того, что я могу вам сказать, заменяйте ленту при каждом обновлении на setFeed(response.data); so, это выглядит как проблема с данными из серверной части. Вы хотите сказать, что после нескольких обновлений ранее определенные данные теперь не определены?

4. да, но только один из них. Однако я проверил отдельно с Postman, и данные, похоже, есть. Поскольку он разбит на страницы, поэтому по 10 элементов за раз, и после этого также есть страницы. Я мог видеть там все десять элементов. Возможно, это useState проблема асинхронности, не уверен. Я пытался периодически регистрироваться, а также добавлять проверки, чтобы избежать undefined значений, но тщетно.