0

I'm working on a project where as form.select is used and I want to be able to pull more data when at the bottom of the list. Is there a way to do this? If so could you point me in the right direction.

I have already tried the Visibility behavior with Semantic and have found little luck.

<Visibility offset={[10, 10]} onUpdate={this.handleUpdate}>
  <Form.Select
    label="Example"
    required={true}
    placeholder="Test Placeholder"
    noResultsMessage="No results found for the selected product"
    fluid={true}
    search={true}
    selection={true}
    clearable={true}
    value={value || ""}
    options={this.state.valueList}
    onChange={this.onChange.bind(value, "value")}
  />
</Visibility>

The Visibility just tracks the Form.Select on the page, not the dropdown selector.

Kegen Guyll
  • 13
  • 1
  • 5
  • I'm sorry but why do you want an infinite scroll? I just don't see the importance. If I were you, I'd put the data in a state array, render it, and everytime there's an update you just push the update to your state array, which will modify the rendered ``Form.Select`` dynamically – josemartindev May 24 '19 at 14:15
  • So I'm pulling from an API but it only gives 10 items at a time. So when the select hits the bottom of the scroll I need it to pull more data :Update: How would I know when to pull more data in that case? – Kegen Guyll May 24 '19 at 14:17
  • I'm sorry but I don't see why you should need this. I will post an example. – josemartindev May 24 '19 at 14:29
  • @josemartindev that would be greatly appreciated – Kegen Guyll May 24 '19 at 14:33

2 Answers2

0

My way is based on "semantic-ui-react": "2.1.4"

const InfiniteDropdown = ({
  options,
  hasNextPage,
  fetchNextOptions,
  ...restProps
}: InifiniteDropdownType & DropdownProps) => {
  const allOptionsRef = useRef<DropdownItemProps[]>([]);

  const renderOptions = useMemo(() => {
    allOptionsRef.current = [...allOptionsRef.current, ...(options || [])];
    const newOptions = [...allOptionsRef.current];
    if (hasNextPage) {
      newOptions.push({
        key: `${newOptions.length}_infinite-loader`,
        content: (
          <Visibility
            onOnScreen={() => {
              console.log("===onScreen!!!");
              fetchNextOptions?.();
            }}
          >
            <Loader active />
          </Visibility>
        ),
      });
    }
    return newOptions;
  }, [options, hasNextPage, fetchNextOptions]);

  return <Dropdown {...restProps} lazyLoad options={renderOptions} />;
};

The "lazyLoad" is required as "Visibility" will only be rendered and "onOnScreen" is been called when the Loader is reached.

Chuck Hsu
  • 36
  • 3
-1

If you have a state array, and you keep adding data dynamically, it will render automatically. Check my demo below. I made a setInterval of 1 second for you to imagine data coming every second. My state array names will update automatically. So, there is no need of having a sort of MORE OPTIONS button or keeping scrolling in your Select, because it will have the info added automatically.

import React, { Component } from 'react';
import './style.css';
import { render } from 'react-dom';

class App extends Component {
  constructor() {
    super();
    this.state = {
      names: ["Person 1", "Person 2", "Person 3", "Person 4"],
      nb: 4
    };
  }

  render() {

    setTimeout(() => {
       const tmp = [...this.state.names]; 
       const num = this.state.nb; 
       num++; 
       tmp.push("Person " + num) 
       this.setState({ names: tmp, nb: num });
    }, 1000);

    return (
      <div>
        <select>
          {this.state.names.map((value) =>
            <option value={value}>{value}</option>
          )}
         </select>  
      </div>
    );
  }
}

render(<App />, document.getElementById('root'));

Demo

josemartindev
  • 1,413
  • 9
  • 17
  • I understand what your saying, but my question is how will I know when to pull more data or are you suggesting just to pull it continuously – Kegen Guyll May 24 '19 at 14:51
  • I modified my answer with a `` – josemartindev May 24 '19 at 14:52
  • If it's data that gets updated every second, well... yeah. Although it is not recommended: For example, if you're making API calls for a service and you have a limited 100 calls per month, you're going to spend all of them in literally 100 seconds. If it's data that get's updated every 10, 20 or 30 minutes, then using a ``setInterval`` like my example should do the trick. – josemartindev May 24 '19 at 14:56