Skip to content
Back to skills

Lynx Ui Feed List

ASecurity

`FeedList` is a high-performance feed stream list component, built upon `List`. It encapsulates common feed scenarios such as **pull-to-refresh** and **load more**, allowing developers to quickly build feed list pages. Note: Use `FeedList` only when you need pull-to-refresh and load-more behaviors. For regular virtual lists without these features, prefer using `List` directly.

  • 119 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added June 5, 2026
developmentreactperformance

Security analysis

A100/100

Pro scans all 19 files and shows the line behind each finding

Scanned September 21, 2026

npx -y skills add lynx-family/lynx-ui --skill lynx-ui-feed-list --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Lynx Ui Feed List?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Lynx Ui Feed List
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/lynx-family-lynx-ui-feed-list/badge)](https://www.skillsdirectory.com/skills/lynx-family-lynx-ui-feed-list)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
# lynx-ui-feed-list SKILL

`FeedList` is a high-performance feed stream list component, built upon `List`. It encapsulates common feed scenarios such as **pull-to-refresh** and **load more**, allowing developers to quickly build feed list pages.

Note: Use `FeedList` only when you need pull-to-refresh and load-more behaviors. For regular virtual lists without these features, prefer using `List` directly.

## 1. Core Capabilities

- **High-Performance Virtual List**: Inherits all the performance features of `List`, including virtual scrolling and multi-layout support (`single`, `flow`, `waterfall`).
- **Pull-to-Refresh**: Enable via `refreshOptions`, supports custom refresh headers.
- **Native Pull-to-Refresh**: Set `refreshOptions.mode` to `'native'` to use the native `<refresh>` element while keeping the same callbacks and ref methods.
- **Load More**: Use `onScrollToLower`, `loadMoreFooter`, and `noMoreDataFooter` to implement pagination states.
- **Gesture Coordination**: Coordinate gestures with parent containers (like `Popup`) via `main-thread:gesture`.

## 2. AI Coding Guide

### Minimal Usable Example

When using `FeedList`, you **MUST** provide `listId` and `listType`, and use `<list-item>` as the direct child. To enable pull-to-refresh and load more, you also need to configure the corresponding props and get the instance via `ref` to control the state.

```tsx
import { useRef } from '@lynx-js/react'
import { FeedList, FeedListRef } from '@lynx-js/lynx-ui'

function BasicFeedList() {
  const feedListRef = useRef<FeedListRef>(null)
  const items = Array.from({ length: 20 }, (_, i) => `Item ${i}`)

  const handleRefresh = () => {
    console.log('Refreshing...')
    setTimeout(() => {
      feedListRef.current?.finishRefresh()
    }, 2000)
  }

  const handleLoadMore = () => {
    console.log('Loading more...')
    // After loading, you might need to call feedListRef.current?.changeHasMoreStatus(false);
  }

  return (
    <FeedList
      ref={feedListRef}
      listId='my-feed-list'
      listType='single'
      refreshOptions={{
        enableRefresh: true,
        mode: 'native',
        headerContent: <text>Refreshing…</text>,
        onStartRefresh: handleRefresh,
      }}
      onScrollToLower={handleLoadMore}
      style={{ width: '100%', height: '500px' }}
    >
      {items.map(item => (
        <list-item item-key={item} key={item}>
          <view style={{ height: '60px' }}>{item}</view>
        </list-item>
      ))}
    </FeedList>
  )
}
```

### Recommended Prompt Formula

> **Scenario Description** + **Layout Configuration** + **Refresh and Load More Logic** + **Custom UI**

**Example Prompt:**

- "Create a single-column `FeedList`. When pulled down, it triggers a refresh operation, and the refresh animation should be stopped after 2 seconds."
- "Implement a two-column grid `FeedList`. When scrolled to the bottom, it triggers a load more function. When there is no more data, display a ‘No more data’ footer."
- "Customize the pull-to-refresh header of `FeedList` to be a Lottie animation."

## 3. Use Cases & Best Practices

### Basic Feed Stream List

A list with pull-to-refresh and load more functionality.

```tsx
import { useRef, useState } from '@lynx-js/react';
import { FeedList, FeedListRef } from '@lynx-js/lynx-ui';

function FullFeaturedFeedList() {
  const listRef = useRef<FeedListRef>(null);
  const [items, setItems] = useState([...]);
  const [hasMore, setHasMore] = useState(true);

  const onRefresh = async () => {
    const newData = await fetchNewData();
    setItems(newData);
    listRef.current?.finishRefresh();
    setHasMore(true); // Reset hasMore status on refresh
    listRef.current?.changeHasMoreStatus(true);
  };

  const onLoadMore = async () => {
    if (!hasMore) return;
    const moreData = await fetchMoreData();
    if (moreData.length > 0) {
      setItems([...items, ...moreData]);
    } else {
      setHasMore(false);
      listRef.current?.changeHasMoreStatus(false);
    }
  };

  return (
    <FeedList
      ref={listRef}
      listId="feed"
      listType="single"
      refreshOptions={{ onRefresh }}
      onScrollToLower={onLoadMore}
      loadMoreFooter={<text>Loading...</text>}
      noMoreDataFooter={<text>-- End --</text>}
    >
      {/* ... list-items ... */}
    </FeedList>
  );
}
```

**Example Path**: `apps/examples/src/FeedList/Basic/index.tsx`

### Grid Layout Feed

Combine `listType: 'flow'` to create a feed in a grid layout.

```tsx
<FeedList
  listId='grid-feed'
  listType='flow'
  spanCount={2}
  {...otherProps}
>
  {/* ... */}
</FeedList>
```

**Example Path**: `apps/examples/src/FeedList/Grid/index.tsx`

### Managing Footer State

FeedList displays two footer variants:

- `loadMoreFooter`: shown when there is more data to load
- `noMoreDataFooter`: shown when all data has been loaded

Footers are controlled exclusively via `ref.current.changeHasMoreStatus(hasMore)`. They are not linked to refresh status or diff results.

```tsx
import { useRef, useState } from '@lynx-js/react'
import { FeedList, FeedListRef } from '@lynx-js/lynx-ui'

function FooterStateExample() {
  const listRef = useRef<FeedListRef>(null)
  const [hasMore, setHasMore] = useState(true)

  const onScrollToLower = () => {
    // fetch more...
    const more = await fetchMore()
    if (more.length === 0) {
      setHasMore(false)
      listRef.current?.changeHasMoreStatus(false) // switch to noMoreDataFooter
    }
  }

  const onRefresh = async () => {
    // refresh resets footer state if needed
    setHasMore(true)
    listRef.current?.changeHasMoreStatus(true) // back to loadMoreFooter
    listRef.current?.finishRefresh()
  }

  return (
    <FeedList
      ref={listRef}
      listId='feed'
      listType='single'
      refreshOptions={{ onRefresh }}
      onScrollToLower={onScrollToLower}
      loadMoreFooter={<text>Loading…</text>}
      noMoreDataFooter={<text>-- End --</text>}
    >
      {/* ... list-items ... */}
    </FeedList>
  )
}
```

### Selecting the Refresh Implementation

`FeedList` uses `useRefreshAndBounce` by default. Set `refreshOptions.mode` to `'native'` when a vertical list should use the platform-native `<refresh>` element instead. The `startRefresh()` and `finishRefresh()` ref methods and the callbacks in `refreshOptions` work in both modes.

```tsx
<FeedList
  ref={listRef}
  listId='native-refresh-feed'
  listType='single'
  scrollOrientation='vertical'
  refreshOptions={{
    enableRefresh: true,
    mode: 'native',
    headerContent: <RefreshHeader />,
    onStartRefresh,
  }}
>
  {/* ... list-items ... */}
</FeedList>
```

Do not set `mode: 'native'` for horizontal lists. Keep the default hook-based mode when custom `bounceableOptions` must coordinate upper-edge bouncing with refresh gestures.

### 4. FAQ

**Q: After triggering `onRefresh`, the refresh header persists. What should I do?**

A: `FeedList` does not automatically end the refresh animation. Call `ref.current.finishRefresh()` after your data request completes; otherwise, the refresh header remains visible.

**Q: After loading all data, the load more footer is still displayed. How do I stop it?**

A: Call `ref.current.changeHasMoreStatus(false)` to indicate there is no more data, and display `noMoreDataFooter` instead of `loadMoreFooter`.

**Q: When should I use `FeedList` vs `List`?**

A: Use `FeedList` only when you need pull-to-refresh and load-more behaviors. For regular virtual lists without these features, prefer using `List` directly.

## 5. Sub components

- **`<list-item>`**: This is a built-in tag, not a React component provided by `lynx-ui`. It must be the direct child of `FeedList` and must have a unique `item-key` and `key` property. All content for a list item should be placed inside this tag.

Files in this skill

  • CHANGELOG.md2.4 KB
  • LICENSE11.1 KB
  • README.md1.3 KB
  • README_zh.md951 B
  • SKILL.md6.6 KB
  • docs/APIReference.mdx40.4 KB
  • docs/README.mdx924 B
  • docs/README.zh.mdx943 B
  • docs/useRefresh.mdx1.3 KB
  • docs/useRefresh.zh.mdx1.4 KB
  • package.json1.2 KB
  • rslib.config.ts338 B
  • src/hooks/useRefresh.ts42.8 KB
  • src/index.tsx11.6 KB
  • src/styles.css630 B
  • src/types/index.docs.ts4 KB
  • src/types/index.ts225 B
  • tsconfig.docs.json122 B
  • tsconfig.json141 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.