Встроенная прокрутка для обновления не работает должным образом с нумерацией страниц

#react-native

#react-native

Вопрос:

я новичок в react native, пожалуйста, потерпите меня. В настоящее время у меня есть flatlist в моем проекте react native, который извлекает сообщения из моего бэкэнда с помощью api. Я успешно реализовал разбиение на страницы в своем бэкэнде, и в моем приложении, когда я прокручиваю до конца, оно добавляет вновь извлеченные сообщения в конец отображаемых текущих сообщений.

Моя проблема в том, что когда я прокручиваю для обновления, я хочу, чтобы отображались только сообщения страницы 0.

Что происходит, так это то, что сообщения на странице 0 добавляются в нижнюю часть сообщений вместо отображения только этих сообщений.

Так, например, когда я загружаю свое приложение, отображаются сообщения на странице 0, и когда я прокручиваю, чтобы обновить, вместо того, чтобы просто показывать сообщения на странице 0, сообщения на странице 0 добавляются в нижнюю часть сообщений на странице 0, и поэтому я получаю сообщение об ошибке, что идентификатор дублируется.

Требуемое действие, которое я пытаюсь выполнить, — это когда я прокручиваю для обновления, я просто хочу, чтобы отображались сообщения на странице 0.

Вот мой код:

 function PostsScreen({ navigation }) {
 const [posts, setPosts] = useState([]);
 const [error, setError] = useState(false);
 const [loading, setLoading] = useState(false);

  const loadPosts = async () => {
  setLoading(true);
  const response = await postsApi.getPosts(page);
  setLoading(false);

  if (!response.ok) return setError(true);

  setError(false);
  setPosts([...posts,...response.data]);
 };

 const[page,setPage]=useState(0);

 useEffect(() => {
 loadPosts(page);
 }, [page]);

const handleLoadMore = ()=>{
console.log('loadmore')
setPage(page 1);
}

 const [refreshing, setRefreshing] = useState(false);

 return (
 <>
  <ActivityIndicator visible={loading} />
  <Screen style={styles.screen}>
    <FlatList
      data={posts} // to have all the data
      keyExtractor={(post) => post.id.toString()}
      renderItem={({ item,index }) => (
        <Card
          title={item.title}
          subTitle={item.subTitle}
          onPress={() => navigation.navigate(routes.POST_DETAILS, {post:item,index})}
        />
      )}
      refreshing={refreshing}
      onRefresh={() => {
        loadPosts(0); // I think the problem is here.//
        setPage(0);
      }}
      onEndReached={handleLoadMore}
      onEndReachedThreshold={0}
      initialNumToRender={10}
    />
  </Screen>
</> 
);
}
 

Заранее благодарю вас.

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

1. извините, вы можете переписать свой вопрос. это трудно понять. Вам нужна страница 1?

2. @SomeoneSpecial привет, моя первая страница — страница 0, я хочу, чтобы при прокрутке для обновления я просто хотел отобразить страницу 0. мой код в настоящее время, когда я прокручиваю для обновления, добавляет страницу 0 к массиву отображаемых страниц. это лучшее объяснение или я должен переписать свой вопрос?

3. можете ли вы опробовать данный код в ответе.

Ответ №1:

Из того, что я прочитал, я полагаю, что вы хотите реализовать разбивку на страницы в своем приложении, и у вас это есть и в вашем коде. Теперь, когда вы пытаетесь обновить свой список, вы просто хотите установить в списке начальные 10 элементов. если это так,

 function PostsScreen({ navigation }) {
  const [posts, setPosts] = useState([]);
  const [error, setError] = useState(false);
  const [loading, setLoading] = useState(false);
  const [page, setPage] = useState(0);
  const [refreshing, setRefreshing] = useState(false);

  const loadPosts = async () => {
    setLoading(true);
    const response = await postsApi.getPosts(page);
    setLoading(false);
    if (refreshing)
      setRefreshing(false);
    if (!response.ok) return setError(true);
    setError(false);
    if (page == 0)
      setPosts(response.data)
    else
      setPosts([...posts, ...response.data]);
  };


  useEffect(() => {
    loadPosts();
  }, [page]);

  const handleLoadMore = () => {
    setPage(page   1);
  };

  const onRefresh = () => {
    setRefreshing(true);
    setPage(0);
  };


  return (
    <>
      <ActivityIndicator visible={loading} />
      <Screen style={styles.screen}>
        <FlatList
          data={posts}
          renderItem={({ item, index }) => (
            <Card
              title={item.title}
              subTitle={item.subTitle}
              onPress={() => navigation.navigate(routes.POST_DETAILS, { post: item, index })}
            />
          )}
          refreshing={refreshing}
          onRefresh={onRefresh}
          onEndReached={handleLoadMore}
          onEndReachedThreshold={0.05}
          keyExtractor={(post) => post.id.toString()}
        />
      </Screen>
    </>
  );
}
 

Это должно решить вашу проблему.

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

1. это решение сработало, спасибо. У меня вопрос, нужен ли мне setRefreshing(true) в функции onRefresh?

2. Мы используем параметр обновления для flatlist, если вы не установите для него значение true, вы больше не увидите индикатор активности в верхней части списка при нажатии вниз. В основном это делается для того, чтобы визуально показать пользователю, что данные загружаются в фоновом режиме. Вы можете прочитать больше об этом в reactnative.dev/ docs/ flatlist#onrefresh

3. поскольку у меня уже есть индикатор активности <ActivityIndicator visible={loading} /> это уже показывает, что данные загружаются

4. ДА. Это больше похоже на компонент управления обновлением. В Android, если вы нажмете на этот список, вы увидите, что индикатор активности перетаскивается из верхней части экрана, как то, что мы видим на этом изображении i2.wp.com/angularscript.com/wp-content/uploads/2016/12 /. … Если это не требуется, вы, конечно, можете удалить это.

Ответ №2:

 
const loadPosts = async () => {
  setLoading(true);
  const response = await postsApi.getPosts(page);
  setLoading(false);

  if (!response.ok) return setError(true);

  setError(false);
  if(page=== 0){
     setPosts(response.data);
  }else{
  setPosts([...posts,...response.data]);
  }
 };


//...

onRefresh={() => {
        setPage(0);
        loadPosts(); // loadPosts takes no argument. 
      }
   }


//...

const handleLoadMore = ()=>{
    console.log('loadmore')
    setPage(page 1);
    loadPosts();
}


 

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

1. привет, я попробовал приведенный выше код, и он работает, когда я прокручиваю, чтобы загрузить больше, а затем обновить, отображаются только сообщения на странице 0, но когда я пытаюсь добавить новое сообщение, а затем обновить, оно не работает.

2. пожалуйста, попробуйте использовать обновленную handleLoadMore() функцию

3. все еще не работает должным образом, я попытаюсь объяснить, что происходит. максимальное количество сообщений на странице равно 10, когда я загружаю свое приложение, отображаются первые 10 сообщений, затем, когда я прокручиваю, чтобы загрузить больше, отображаются следующие 10 сообщений. Когда я обновляю, первые 10 сообщений отображаются правильно. теперь, когда я добавляю новое сообщение и пытаюсь обновить, оно показывает 20 сообщений вместо всего 10 сообщений.

4. функция работает отлично, вам просто нужно нарезать элементы, отображаемые в виде плоского списка, чтобы показать страницу, на которой вы находитесь. в FlatList попробуйте использовать data: {posts.slice(page*10)}

5. когда я добавил данные: {posts.slice (страница)}, когда я попытался загрузить больше, он перешел прямо на страницу 10