beforesemicolon / flatlist-react Goto Github PK
View Code? Open in Web Editor NEWA helpful utility component to handle lists in react like a champ
License: MIT License
A helpful utility component to handle lists in react like a champ
License: MIT License
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.
the renderItem is now called with an index of the item and as a 3rd parameter it should include the item id or generate one
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?
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
Not a bug, closing
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
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):
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
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):
Smartphone (please complete the following information):
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.
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:
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
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)
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.
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.
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.
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.
Support for defaultProps will be removed from function components in a future major release. Use JavaScript default parameters instead.
FunctionComp.defaultProps is going to be deprecated in React 18.3.0
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):
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.
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
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):
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
An optional prop for search that allows controlling the search delay
Allow providing regex as a search term. This is done by detecting wild cards like ^, *, $, .(dot)
Example of search term: ^Sample, .mp4$, bo.
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
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.