The problem: I have a FlashList that uses React Context to fill in the data (the data is an array of objects that renders a View) but when I update the context and the extraData
prop for FlashList, the list does not re-render, or re-renders sometimes, or takes multiple events to actually re-render.
The Code:
// Many imports, they are all fine though
export default () => {
// Relevant context.
const {
cardsArray,
cardsArrayFiltered,
updateCardsArray,
updateCardsArrayFiltered
} = useContext(AppContext);
// Relevant state.
const [didUpdateCards, setDidUpdateCards] = useState(false);
const [cardsFilters, setCardsFilters] = useState([]);
// Relevant refs.
const flatListRef = useRef(null);
// Example effect on mount
useEffect(() => {
setInitialAppState();
}, []);
// Effect that listen to changing on some data that update the context again
useEffect(() => {
const newCardsArray = doSomeFiltering(cardsArray, cardsFilters);
updateCardsArrayFiltered(newCardsArray);
setDidUpdateCards(!didUpdateCards);
}, [cardsFilters]);
// Example of promisey function that sets the initial context.
const setInitialAppState = async () => {
try {
const newCardsArray = await getPromiseyCards();
updateCardsArrayFiltered(newCardsArray);
updateCardsArray(newCardsArray);
} catch ( err ) {
console.debug( err );
}
}
// Renderer for the list item.
const renderListItem = useCallback((list) => <Card key={list.index} card={list.item} />, []);
// List key extractor.
const listKeyExtractor = useCallback((item) => item.id, []);
return (
<FlashList
ref={flatListRef}
data={cardsArrayFiltered}
extraData={didUpdateCards}
keyExtractor={listKeyExtractor}
renderItem={renderListItem}
showsVerticalScrollIndicator={false}
estimatedItemSize={Layout.window.height}
/>
);
}
Notes:
- What I did not write all out is the function, logic, view to update
cardsFilters
however the above effect IS running when it changes. - Moreover, this line here,
const newCardsArray = doSomeFiltering(cardsArray, cardsFilters);
does indeed return the proper updated data.
What's going on here? I am updating the extraData
prop with that didUpdateCards
state when the context changes which I thought was the requirement to re-render a FlatList/FlashList.
The problem: I have a FlashList that uses React Context to fill in the data (the data is an array of objects that renders a View) but when I update the context and the extraData
prop for FlashList, the list does not re-render, or re-renders sometimes, or takes multiple events to actually re-render.
The Code:
// Many imports, they are all fine though
export default () => {
// Relevant context.
const {
cardsArray,
cardsArrayFiltered,
updateCardsArray,
updateCardsArrayFiltered
} = useContext(AppContext);
// Relevant state.
const [didUpdateCards, setDidUpdateCards] = useState(false);
const [cardsFilters, setCardsFilters] = useState([]);
// Relevant refs.
const flatListRef = useRef(null);
// Example effect on mount
useEffect(() => {
setInitialAppState();
}, []);
// Effect that listen to changing on some data that update the context again
useEffect(() => {
const newCardsArray = doSomeFiltering(cardsArray, cardsFilters);
updateCardsArrayFiltered(newCardsArray);
setDidUpdateCards(!didUpdateCards);
}, [cardsFilters]);
// Example of promisey function that sets the initial context.
const setInitialAppState = async () => {
try {
const newCardsArray = await getPromiseyCards();
updateCardsArrayFiltered(newCardsArray);
updateCardsArray(newCardsArray);
} catch ( err ) {
console.debug( err );
}
}
// Renderer for the list item.
const renderListItem = useCallback((list) => <Card key={list.index} card={list.item} />, []);
// List key extractor.
const listKeyExtractor = useCallback((item) => item.id, []);
return (
<FlashList
ref={flatListRef}
data={cardsArrayFiltered}
extraData={didUpdateCards}
keyExtractor={listKeyExtractor}
renderItem={renderListItem}
showsVerticalScrollIndicator={false}
estimatedItemSize={Layout.window.height}
/>
);
}
Notes:
- What I did not write all out is the function, logic, view to update
cardsFilters
however the above effect IS running when it changes. - Moreover, this line here,
const newCardsArray = doSomeFiltering(cardsArray, cardsFilters);
does indeed return the proper updated data.
What's going on here? I am updating the extraData
prop with that didUpdateCards
state when the context changes which I thought was the requirement to re-render a FlatList/FlashList.
3 Answers
Reset to default 4@Staghouse your ponent contains key property, and official docs remend to remove it: https://shopify.github.io/flash-list/docs/fundamentals/performant-ponents/#remove-key-prop :
"Using key prop inside your item and item's nested ponents will highly degrade performance.
Make sure your item ponents and their nested ponents don't have a key prop. Using this prop will lead to FlashList not being able to recycle views, losing all the benefits of using it over FlatList."
Hope this helps.
It looks like object being passed as extraData
is a boolean. This means that if the previous value was true, setting it as true again wouldn't count as a change. Instead use an object and update it when you want list to update.
To try just set extraData={{}}
. if everything works as expected it means that your update logic has some problem.
Try using Shallow Copy when you update data
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742350137a4427347.html
评论列表(0条)