@evo/fetch-holder v0.0.2
FetchHolder
Компонент используется для списков с догружаемыми элементами при скроле страницы.
Dependencies
  "peerDependencies": {
    "prop-types": "^15.7.2",
    "react": "^16.8.2",
    "react-dom": "^16.8.2"
  },
  "devDependencies": {
    "@babel/core": "^7.1.2",
    "@babel/preset-env": "^7.3.1",
    "@babel/preset-react": "^7.0.0",
    "babel-cli": "^6.26.0",
    "babel-loader": "^8.0.4",
    "webpack": "^4.29.5",
    "webpack-cli": "^3.2.3"
  },
  "dependencies": {
    "react-visibility-sensor": "^5.1.0"
  }Usage
import FetchHolder from '@evo/fetch-holder';
const Example = () => (
    const [fetchLoading, setFetchLoading] = useState(false);
    
    const handleLoadMore = () => {
        ...
    }
    <div className={css.root}>
        <FetchHolder
            isLoading={fetchLoading}
            onFetch={handleLoadMore}
        >
            <ul className={css.list}>
                {list.map((item) => (
                    <li
                        key={item}
                        className={css.item}
                    >
                        {item}
                    </li>
                ));
            </ul>
        </FetchHolder>
);API
FetchHolder.propTypes = {
    children: PropTypes.node,
    offset: PropTypes.oneOfType([
        PropTypes.number,
        PropTypes.shape({
            top: PropTypes.number,
            right: PropTypes.number,
            bottom: PropTypes.number,
            left: PropTypes.number
        })
    ]),
    moreComponent: PropTypes.func,
    lazyLoadEnable: PropTypes.bool,
    showMoreEnable: PropTypes.bool,
    isLoading: PropTypes.bool,
    onFetch: PropTypes.func,
};Default значения
FetchHolder.defaultProps = {
    offset: {
        top: 0,
        right: 0,
        bottom: 0,
        left: 0
    },
    lazyLoadEnable: true,
    showMoreEnable: true,
};children
Можно передавать непосредственно список с .map элементов, либо другой компонент
    <FetchHolder>
        <ul>
            {list.map((item) => (
                <li key={item}>{item}</li>
            ));
        </ul>
    </FetchHolder>
);    <FetchHolder>
        <List items={items} />
    </FetchHolder>
);showMoreEnable (bool)
Если больше нет возможности догружать элементы в список стоит указать значение showMoreEnable: false
При этом  не будет  срабатывать дозагрузка при скроле и будет скрыт элемент moreComponent
lazyLoadEnable (bool)
Если нужно отключить дозагрузку э лементов при скроле, а оставить только нажатие на кнопку стоит указать значение lazyLoadEnable: false
offset
По умолчанию значение 0. Это означает что событие onFetch произойдет в момент, когда элемент moreComponent
пересечет любым своим краем границы viewport.
Можно указать значение с типом number - offset={-100}, в таком случае для всех сторон будет увеличена зона viewport на 100 пикселей, тоесть событие произойдет раньше появления элемента во viwport, в тот момент когда к нему  останется < 100 пикселей.
Также можно значением offset указывать объект с нужными нам  ключами top, right, bottom, left.
Например  offset={{ bottom: -200 }}. В таком случае, при скроле страницы вниз событие onFetch произойдет на "200 пикселей" раньше, чем moreComponent станет видимым.
onFetch (func)
Событие, которое произойдет при появлении во viewport с учетом указанных значений offset
isLoading (bool)
После вызова события onFetch, которое инициализирует дозагрузку, нужно менять состояние isLoading на true.
И возвращать isLoading={false} после окончания дозагрузки. При положительном значении повторно не будет срабатывать событие при появлении moreComponent во viewport.
moreComponent (func)
Функция рендера контента под списком <ul> который может содержать в себе кнопку для загрузки при нажатии. При указанном
moreComponent и активном lazyLoadEnable дозагрузка бует происходить при попадании именно этого контента во viewport.
Если moreComponent не указан, дозагрузку будет происходить при попадании во viewport нижней  границы  списка <ul>
    <FetchHolder
        isLoading={loading}
        moreComponent={() => (
            <div style={{ textAlign: 'center' }}>
                <span onClick={!loading ? () => handleLoadMore : null}>
                    {loading ? 'загрузка' : 'показать еще'}
                </span>
            </div>
        )}
        onFetch={handleLoadMore}
    >
        <ul>
            {list.map((item) => (
                <li key={item}>{item}</li>
            ));
        </ul>
        {isLoading ? <Spinner /> : null}
    </FetchHolder>
);6 years ago