Giter VIP home page Giter VIP logo

flatlist-react's People

Contributors

dependabot[bot] avatar ecorreia45 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

flatlist-react's Issues

Invalid DOM property `class`

I think we should change class for className in the documentation — is misleading; if you allow me, I can make a PR for this
image

Memory leak when renderOnScroll is used

Describe the bug
Error on the console stating the leak, state cannot be updated on unmounted component.

When list is updated it does not re render the list. Blank.

Problem with load more data

FlatList Version
1.5.0

React Version
17.0.2

Describe the bug
When I reach the end of the list, no more data is loaded
Here is my `code:

const Dashboard = (): ReactElement => {
  const [memes, setMemes] = useState<Array<any>>([]);
  const [nextMemeOffset, setNextMemeOffset] = useState<number>(0);
  const [hasMoreItems, setHasMoreItems] = useState<boolean>(false);
  const [loading, setLoading] = useState<boolean>(true);

  useEffect(() => {
    loadMoreMemes();
  }, []);

  const loadMoreMemes = () => {
    const list = memes;
    setLoading(true);
    MemeService.getMemes(nextMemeOffset, 2).then(loadedMemes => {
      if (loadedMemes.length !== 0) {
        for (const memeItem of loadedMemes.allMemes) {
          list.push(memeItem);
        }
        setMemes(prevState => {
          prevState = list;
          return _.cloneDeep(prevState);
        });
        setNextMemeOffset(list.length);
        setLoading(false);
        setHasMoreItems(true);
      } else {
        setHasMoreItems(false);
      }
    });
  };

  const renderBlank = () => {
    if (memes.length === 0 && loading) {
      return <div>Loading list ...</div>;
    }
    return <div> List has no items yet!</div>;
  };

  const renderMeme = (meme: any, idx: number) => {
    return <Meme memes={memes} meme={meme} key={idx} memeActionActive={true} />;
  };

  return (
    <ListGroup horizontal={'lg'}>
      <ListGroup.Item style={{ width: '15%', border: 'none' }}>
        <Filter />
      </ListGroup.Item>
      <ListGroup.Item
        style={{ width: '70%', border: 'none', overflow: 'auto' }}>
        <FlatList
          list={memes}
          renderItem={renderMeme}
          renderWhenEmpty={renderBlank}
          hasMoreItem={hasMoreItems}
          loadMoreItems={loadMoreMemes}
        />
      </ListGroup.Item>
      <ListGroup.Item style={{ width: '15%', border: 'none' }}>
        <small>renders</small>
      </ListGroup.Item>
    </ListGroup>
  );
};`

what is the error, why no further data is loaded?

Types forcing to specify values for keys with defaults

FlatList Version
: latest 1.5.6

Describe the bug
: for example the “scrollToTop” does not accept just the boolean and when specifying the option it requires all the fields

Steps to reproduce the behavior
: set a “scrollToTop” on the flat list

Expected behavior
: should leave options optional and recognize different value types

render in reverse order

this is a simple option to allow scrolling up to view more content similar to a chat. Everything else should continue to work as normal and the big challenge here is the render on scroll

SSR: hydration issues on Next.js

FlatList Version
: 1.5.3

Describe the bug
When <FlatList /> is used in a page, the server-side rendered version and the client version cannot be reconciliated, and hydration fails. Read more about hydration error here: https://nextjs.org/docs/messages/react-hydration-error

Steps to reproduce the behavior
: Add <FlatList /> component on a page. list prop can even be an empty array. E.g:

<FlatList
  list={[]}
  renderItem={() => (
    <div />
  )}
/>

Expected behavior
: Hydration should succeed and Next.js should not throw an error

Desktop (please complete the following information):

  • OS: macOS Ventura (13.0)
  • Browser: Safari
  • Version: 16.1

Screenshots
Screenshot 2022-11-01 at 17 53 04

Loading more items on every scroll event

When we setup the flatlist with hasmoreitems and pagination we seem to be experiencing an odd loading behaviour on scroll. If the cursor is outside the region of the flatlist and you scroll all the way to the bottom of the list no event is triggered to load more items. This may be a totally separate issue but we do not know why this is happening. However, when you scroll inside the region of the flatlist it seems like the hasmoreitems fires on every scroll event loading more items to the list each time.

To reproduce this:

this.state = {
      hasMoreItems: false,
}

getUsersProfilesList = async () => {
  return await client.service("users").find({
      query: {
        $limit: 10,
        $skip: this.state.profiles.length,
      }
    }).then((profilesPage) => {
      this.setState(prevState => ({
        hasMoreItems: profilesPage.data.length === profilesPage.limit,
        profiles: [...prevState.profiles, ...profilesPage.data],
        loading: false
    }))
  })
}

render() { 
            <FlatList
              list={this.state.profiles}
              renderItem={this.renderUserProfile}
              renderWhenEmpty={() => <div style={{ flex: 1, textAlign: "center" }}>List is empty!</div>}
              hasMoreItems={this.state.hasMoreItems}
              loadMoreItems={this.getUsersProfilesList}
            />
}

Here's the full example:

import React, { Component } from "react";
import Dropdown from 'react-dropdown';
import 'react-dropdown/style.css';
import FlatList from 'flatlist-react';
import UserProfileComponent from "../components/UserProfileComponent";
import UserFlaggedPost from "../components/UserFlaggedPost";
import moment from 'moment';

const feathers = require('@feathersjs/feathers');
const socketio = require('@feathersjs/socketio-client');
const authentication = require('@feathersjs/authentication-client');
const io = require('socket.io-client');

const socket = io("https://dev.mysite.com", {
  transports: ['websocket'],
  upgrade: false,
});

// Initialize our Feathers client application through Socket.io
// with hooks and authentication.
const client = feathers();

client.configure(socketio(socket));
client.configure(authentication({
  storage: localStorage
}))

const options = [];

class User extends Component {
  constructor(props) {
    super(props)
    this.state = {
      hasMoreItems: false,
      offset: 0,
      loading: true,
      profiles: [],
      value: 1,
      usersFlagged: [ ],
    };

    this.defaultOption = "Select date...";
    for (let i = 0; i < 13; i++) {
      if (i !== 12) {
        options.push({
          value: i,
          label: moment().subtract(i, "month").startOf("month").format('MMM') + '-' + moment().subtract(i - 1, "month").startOf("month").format('MMM') + ' ' + moment().subtract(i, "month").year()
        });
      } else {
        options.push({
          value: i,
          label: "None"
        });
      }
    }
  }

  async componentDidMount() {
    await client.authenticate({
      strategy: "local",
      uname: '...',
      pword: '...',
      extraProps: {
        // tells the server what functionality the client's app version supports
        apiVersion: '2',
      },
    });
    await this.getUsersProfilesList();
  }

  renderUserProfile = (item, idx) => {
    return (
      <UserProfileComponent key={idx} item={item} />
    );
  }

  renderUserFlaggedPost = (item, idx) => {
    return (
      <UserFlaggedPost key={idx} item={item} />
    );
  }

  getUsersProfilesList = async () => {
    //console.log("******************************* before skip: " + this.state.profiles.length + ", this.hasMoreItems=" + this.state.hasMoreItems)
    return await client.service("users").find({
      query: {
        $limit: 10,
        $skip: this.state.profiles.length,
      }
    }).then((profilesPage) => {
      this.setState(prevState => ({
        hasMoreItems: profilesPage.data.length === profilesPage.limit,
        profiles: [...prevState.profiles, ...profilesPage.data],
        loading: false
      }))
      //console.log("******************************* AFTER this.state.profiles.length: " + this.state.profiles.length + ", returned skip: " + profilesPage.skip + ", this.hasMoreItems=" + this.state.hasMoreItems)
    })
      .catch(error => console.log(error.message));
  }

  getUsersProfilesByMonth = async (start, end) => {
    this.setState({ profiles: [] })
    return await client.service("users").find({
      query: {
        createdAt: {
          $lte: end,
          $gte: start,
        },
        $limit: 10,
        $skip: this.state.profiles.length,
      }
    }).then((profilesData) => {
      this.setState(prevState => ({
        hasMoreItems: profilesData.data.length === profilesData.limit,
        profiles: [...prevState.profiles, ...profilesData.data],
        loading: false
      }))
    })
  }

  searchByMonth = async (option) => {
    let timeStart = 0;
    let timeEnd = 0;

    for (let i = 0; i < 13; i++) {
      if (option.value === i) {
        if (i !== 12) {
          this.defaultOption = option.label;
          timeStart = moment().subtract(i, 'months').startOf('month').valueOf();
          timeEnd = moment().subtract(i, 'months').endOf('month').valueOf();
          //console.log ("timeStart = " + moment().subtract(i, 'months').startOf('month').format("YYYY-MM-DD"));
          //console.log ("timeEnd = " + moment().subtract(i, 'months').endOf('month').format("YYYY-MM-DD"));
          await this.getUsersProfilesByMonth(timeStart, timeEnd);
        } else {
          await this.setState({ profiles: [] })
          await this.getUsersProfilesList();
          this.defaultOption = "Select date...";
        }
      }
    }
  }

  render() {

    return (
      <div style={this.state.profiles.length < 3 ? { width: 950, height: window.innerHeight } : { width: 950 }}>
        <div style={{ flex: 1, flexDirection: "row", display: "flex" }}>
          <img src={require("../images/single-02.svg")} alt="user" style={{ height: 25, width: 25, paddingLeft: 30, paddingRight: 10, paddingTop: 30, filter: "brightness(0) saturate(100%)" }} />
          <h2 style={{ paddingTop: 10, color: "#000000", fontWeight: 600 }}>Users</h2>
        </div>
        <div style={{ flex: 1, flexDirection: "row", display: "flex" }}>
          <div style={{ flex: 1 }}>
            <div style={{ flex: 1, flexDirection: "row", display: "flex", justifyContent: "space-between" }}>
              <p style={{ fontSize: 16, fontWeight: 600, paddingLeft: 50, paddingTop: 10 }}>New</p>
              <Dropdown
                options={options}
                onChange={this.searchByMonth}
                value={this.defaultOption}
                placeholder={this.defaultOption} />
            </div>
            <FlatList
              list={this.state.profiles}
              renderItem={this.renderUserProfile}
              renderWhenEmpty={() => <div style={{ flex: 1, textAlign: "center" }}>List is empty!</div>}
              hasMoreItems={this.state.hasMoreItems}
              loadMoreItems={this.getUsersProfilesList}
            />
          </div>
          <div style={{ flex: 1 }}>
            <div style={{ flex: 1, flexDirection: "row", display: "flex", justifyContent: "space-between" }}>
              <p style={{ fontSize: 16, fontWeight: 600, paddingLeft: 50, paddingTop: 10 }}>Flagged</p>
              <Dropdown
                options={options}
                onChange={this.searchByMonth}
                value={this.defaultOption}
                placeholder="Select Date" />
            </div>
            <FlatList
              list={this.state.usersFlagged}
              renderItem={this.renderUserFlaggedPost}
              renderWhenEmpty={() => <div style={{ flex: 1, textAlign: "center" }}>There are no results for this date. Try again.</div>}
            />
          </div>
        </div>
      </div>
    );
  }
}

export default User;

**Desktop (please complete the following information):**
 - OS: Windows/Mac
 - Browser: Chrome
 - Version: 84.0.4147.105 (Official Build) (64-bit)
- React and React Dom 16.8.0

renderOnScroll causing bug

FlatList Version
:1.4.3

Describe the bug
: Enabling renderOnScroll throws error when searchTerm doesnt match any elements
Steps to reproduce the behavior
:
Set renderOnScroll to true
search props:

search={{
            by: ["title", "message"],
            term: searchTerm,
            caseInsensitive: true,
          }}

Render around 400 elements.
set searchTerm to something like "8218132873873nrui3" so that it wont match anything.
set searchTerm to something that will match a few elements.

Expected behavior
:after a short moment error will appear: TypeError: Cannot set property 'scrollTop' of null

Desktop (please complete the following information):

  • OS: Windows
  • Browser: Chrome
  • Version:87.0.4280

Smartphone (please complete the following information):

  • Device:
  • OS:
  • Browser:
  • Version:

Screenshots
image
image
image

Help - Scroll to top?

Question: Is there a way to scroll the flatlist to the top?

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

load more seems to doesn't work

FlatList Version
1.5.14

Describe the bug
Load more seems not to work even though I specified both loadMoreItems and hasMoreItems, see the code snipped below.
The UI lib I'm using is MUI material

<Box
      bgcolor={'white'}
      border={'solid 1px #d9d9d9'}
      overflow={'auto'}
      display={'flex'}
      flex={1}
      pr={2}
      pl={2}
      flexDirection={'column'}
      maxHeight={'46vh'}
      borderRadius={2}
      id={'scroll-container'}
    >
      ...
      {initialLoading ? (
        <Box
          display={'flex'}
          flex={1}
          justifyContent={'center'}
          alignSelf={'stretch'}
          alignItems={'center'}
        >
          <Loader />
        </Box>
      ) : (
        <FlatList
          list={tasks}
          renderItem={(t: Task) => <TaskItem key={t.id} task={t} />}
          filterBy={(t: Task) => !!t.name.match(searchValue)}
          renderWhenEmpty={() => <EmptyScreen />}
          loadMoreItems={() => console.log('QUADRO')}
          hasMoreItems={true}
          renderOnScroll
        />
      )}
    </Box>

Steps to reproduce the behavior
In the case you need an access to the repository to bebug the problem, provide me with an email

Expected behavior
Scrolling to the bottom triggers loadMoreItems function

Desktop:

  • OS: Windows 10
  • Browser: Chrome
  • Version: 114.0.5735.248 (Official Build) (64-bit)

load more items function gets called before user scrolls to bottom when scrollbar is not a parent of flatlist

Is your feature request related to a problem? Please describe.
load more items function gets called before user scrolls to bottom when scrollbar is not a parent of flatlist

Describe the solution you'd like
Option to pass id of scrollbar container if it is not the direct parent of flatlist

Additional context
Sometimes it is not possible to add scrollbar as a parent to flatlist in these cases we need a option to pass id or class of scrollbar container so that flatlist knows it is not a direct parent of container

loadMoreItems would not fire

I'm trying out the library, and so far it's good.
I have a problem, though.

I have to render 13,000 rows, currently I'm slicing the results (I though the library would do this by itself, as FlatList in React Native does)

Code:

 <FlatList 
					  loadMoreItems={this.sliceMoreWork} 
					  hasMoreItems={true} 
					  list={this.props.works.rows.slice(0,500)} 
					  renderItem={this._renderWorkRow}/>

I tried to make it a function, as loadMoreItems={() => this.sliceMoreWork()}
but so far, no luck.

Note: It's firing at the start (without even scrolling). So I suspect it must have something to do with scroll and height container. Tried to absolute them, with diferent overflows, but the same..

Enviroment: Mac OS Electron App (v7)

Group header and footer

The only way to separate the groups is with a separator and that should be optional and should include a renderGroupHeader and renderGroupFooter that is called for each group passing info of the group and should return a component to render at the group top or bottom. Use only when available.

TypeScript: type `renderItem` function to an element of `list` prop

Is your feature request related to a problem? Please describe.
The first parameter of the renderItem function is being typed as any and is therefore not type-safe.

Describe the solution you'd like
Ideally, <FlatList /> should infer the type from the list prop. React Native's <FlatList /> component supports this.

Describe alternatives you've considered
The current workaround is to manually set the type when defining the function. It's less than ideal because it's a manual step and it's not helping keep the code lean.

Index is index within group not overall

In renderItem, the index being passed in is the index of an item within a group. This means when grouping is used, there is no overall "unique" index that can ID an object. Makes poking and prodding at elements a bit difficult!

Even having a "groupidx" and a regular idx to uniquely ID each item would be useful.

display="table"

similar to display row and display grid there should be an option to render the list as a table. This should also include renderTableHeader, renderTableFooter, and use renderItem or provide a renderTableRow as an alias to renderItem.

NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.

Describe the bug
flatlist-react gets super unhappy if dynamically removed from a page.

To Reproduce
Steps to reproduce the behavior:
Conditionally render flatlist-react, do something that causes it to no longer render and then to render again.

Expected behavior
flatlist-react is happy being removed/added from a page.

Screenshots
NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.

Desktop (please complete the following information):

  • Browser [e.g. chrome, safari]: Chrome

Additional context
Trying to swap out my scrollbars when going to a grid layout when transitioning between screen widths, rendering a different flatlist-react causes the above errors.

Lots of other ways to get it to happen as well. :/ I've ran into this a view times.

Help - Dynamic Filtering

is there a way to dynamically filter items in a FlatList? Say I wanted to filter items based on today's date, tomorrow's date, etc, how could I go about changing/updating the filterBy prop function dynamically?

e.g.

filterBy={item => (item.date > '6-20-20'); // all items past todays date
to
filterBy={item => (item.date == '6-20-20') // all items happening today

load more items function gets called before user scrolls to bottom

FlatList Version
: "1.5.14"

Describe the bug
: load more items function gets called before user scrolls to bottom

Steps to reproduce the behavior
: implement flatlist-react with pagination on it do not use wrapperHtmlTag and style

Expected behavior
: When first list renders user scrolls to bottom of list then the loadmoreitems function is called.

Desktop (please complete the following information):

  • OS: Windows
  • Browser: Chrome
  • Version: latest

Scroll to top button not resetting

Lets say the list clears and then populated the scroll to top button appears from start, not detecting that the list is new and the scroll position is at the top

Search Delay Prop

An optional prop for search that allows controlling the search delay

Regex Search

Allow providing regex as a search term. This is done by detecting wild cards like ^, *, $, .(dot)

Example of search term: ^Sample, .mp4$, bo.

Scroll to Item or index

Allow a prop that when set, would automatically scroll to that specific item. This should work with the renderOnScroll prop set. It only scrolls to the item if the current value is different than the previous and the item actually exists

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.