-1

I want to implement something like infinity scrolling on my application. This is my code:

import React, { useState, useEffect } from "react";

import AsyncSelect from "react-select/async";

const WithPromises = () => {
  const [page, setPage] = useState(1);
  const [allData, setAllData] = useState([]); //here should be added all data
  const [scrolll, setScrolll] = useState();
  const filterData = (inputValue) => {
    const req = fetch(
      `https://jsonplaceholder.typicode.com/todos?_limit=15&_page=${page}`
    )
      .then((response) => response.json())
      .then((res) => {
        const fetchedData = res.map(({ title }) => {
          return {
            label: title,
            value: title
          };
        });
        page > 1 && setAllData([...allData, ...fetchedData]);
        return [...fetchedData, allData];
      });
    return req;
  };

  const promiseOptions = (inputValue) => {
    return filterData(inputValue);
  };

  const scroll = (e) => {
    console.log(e);
    setScrolll(e);
    promiseOptions();
  };

  useEffect(() => {
    setPage(page + 1);
  }, [scrolll, page]);

  return (
    <AsyncSelect
      cacheOptions
      onMenuScrollToBottom={scroll}
      isClearable={true}
      isSearchable={true}
      defaultOptions
      loadOptions={promiseOptions}
    />
  );
};

export default WithPromises;

How you can see, i increment the page when the scroll section is at the bottom: setPage(page + 1);. This value is added in the api https://jsonplaceholder.typicode.com/todos?_limit=15&_page=${page}.
Also i want to concat all data from each scroll here: return [...fetchedData, allData]. At the end i need to achieve something like this: User scrolls down and in the scroll section are added mew values, but previous should't dissapear, so on every scrolling when the scroll bar is at the bottom the new data should be added at the bottom of the select.
Issue: I can't achieve what i described above and i don't know the issue.
Question: How to solve the issue in my situation?
demo: https://codesandbox.io/s/codesandboxer-example-forked-zsj6i?file=/example.js:0-1262

1 Answer 1

1
import React, { useState, useEffect } from "react";

import AsyncSelect from "react-select/async";

const WithPromises = () => {
  const [page, setPage] = useState(1);
  const [items, onItemsChange] = useState([]);

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

  const fetchData = async (pageIdx) => {
    const res = await fetch(
      `https://jsonplaceholder.typicode.com/todos?_limit=15&_page=${pageIdx}`
    ).then((r) => r.json());
    const resItems = res.map(({ title }) => ({
      label: title,
      value: title
    }));
    onItemsChange([...items, ...resItems]);
  };

  const loadOptions = () => items;

  // for search functionality use something like this:
  // const loadOptions = async (inputStr) => {
  //   const searchRes = await fetch(`${yourUrl}?search=${inputStr}`).then(r => r.json());
  //   return searchRes;
  // };

  const handleBottomScroll = () => {
    setPage((prevVal) => prevVal + 1);
  };

  return (
    <AsyncSelect
      cacheOptions
      isClearable={true}
      isSearchable={true}
      defaultOptions={items}
      onMenuScrollToBottom={handleBottomScroll}
      loadOptions={loadOptions}
    />
  );
};

export default WithPromises;
Sign up to request clarification or add additional context in comments.

11 Comments

your answer is great. I have one question, if i will implement a search feature on this, the options will be updated according to the searched value? PS: i want to keep the infinite scrolling also
to add support of "search" functionality you need to update loadOptions method. It should fetch data from API with search parameter and return it. You don't need to set it to state, just return.
according to jsonplaceholder documentation i can search items by id like this: https://jsonplaceholder.typicode.com/todos?_limit=15&_page=${pageIdx}/${searchedId}, but i changed code and it does not work. You can see updateted sanbox
now you can see that if i search i don't get results in the dropdown. Could you please take a look why the search does not work? Thanks in advance.
what do you think about the issue?
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.