admin管理员组文章数量:1336728
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
版权声明:本文标题:javascript - React Native + Context + FlashList wont re-render with Context update + extraData updating - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742350137a2458323.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论