'Why my Flatlist are not rerendering when states changes?
I have a list of users. I want to set one person to mute. In my redux store its updated fine. But its not rerender although I use extraData. But Why?
UserList/Bottomsheet
import * as React from 'react';
import { StyleSheet, Text, View, Pressable, Image, Dimensions, Animated } from 'react-native';
import BottomSheet, { BottomSheetFlatList } from '@gorhom/bottom-sheet';
import { chatMock, chatMockFlat } from '../../../utils/mockChat';
import { AntDesign, Ionicons } from '@expo/vector-icons';
import { useSelector, useDispatch, shallowEqual } from 'react-redux';
import { handleSetMuteOn } from '../../../redux/slice/chat/chatSlice';
const { width } = Dimensions.get('window');
function propsEqual(prevName, nextName) {
return prevName.isMuted === nextName.isMuted;
}
const Item = React.memo(({ name, date, image, id, text, modal, fixed, muted, onPressMute }) => {
console.log('RERENDERs');
return (
<Pressable delayLongPress={100} onLongPress={() => modal(id)} style={s.chatItem}>
<View style={s.viewLeftImage}>
<Pressable onPress={onPressMute} style={s.imagePress}>
<Image source={{uri: image}} style={s.profile_image} resizeMode='contain' />
<View style={s.onlineStatus}></View>
</Pressable>
</View>
<View style={s.viewMidText}>
<View style={s.viewHeaderText}>
<View style={s.nameContainer}>
<Text style={s.name}>{name}</Text>
{ fixed === 1 && (
<View style={s.pinContainer}>
<AntDesign name="pushpino" size={12} color="#bbb" />
</View> )
}
{ muted === 1 && (
<View style={s.pinContainer}>
<Ionicons name="volume-mute-sharp" size={12} color="#bbb" />
</View> )
}
</View>
<Text style={s.date}>{date}</Text>
</View>
<Text style={s.text}>{text}</Text>
</View>
</Pressable>
)
}, propsEqual);
const userState = state => state.chatSlice.userList;
const BottomSheetChat = ({ Modal }) => {
const userList = useSelector(userState);
const dispatch = useDispatch();
const [refresh, setRefresh] = React.useState(false);
const handleMuteChat = React.useCallback(() => {
setRefresh(!refresh);
dispatch(handleSetMuteOn());
}, [dispatch]);
const bottomSheetRef = React.useRef(null);
// variables
const snapPoints = React.useMemo(() => ['25%', '100%'], []);
const renderItem = ({ item }) => (
<Item
name={item.name}
date={item.date}
image={item.image}
id={item.id}
text={item.text}
fixed={item.isFixed}
modal={(e) => Modal(e)}
muted={item.isMuted}
onPressMute={handleMuteChat}
/>
)
return (
<View style={s.container}>
<BottomSheet
ref={bottomSheetRef}
index={1}
style={s.sheetContainer}
snapPoints={snapPoints}
handleStyle={{borderTopLeftRadius: 16, borderTopRightRadius: 16,}}
>
<BottomSheetFlatList
data={userList}
keyExtractor={i => i.id}
renderItem={renderItem}
extraData={refresh}
>
</BottomSheetFlatList>
</BottomSheet>
</View>
)
};
Slice:
import { createSlice } from "@reduxjs/toolkit";
import { chatMockFlat } from "../../../utils/mockChat";
const chatSlice = createSlice({
name: 'chatSlice',
initialState: {
unreadChats: 0,
headerSearchChats: '',
currentUserID: null,
modalOpen: false,
userList: chatMockFlat
},
reducers: {
handleSetMuteOn(state, action) {
state.userList = state.userList.map(el => {
if(state.currentUserID === el.id) {
return {
...el,
isMuted: 1
}
} else {
return {
...el
}
}
});
},
handleSetMuteOff(state, action) {
state.userList = state.userList.map(el => {
if(state.currentUserID === el.id) {
return {
...el,
isMuted: 0
}
} else {
return {
...el
}
}
});
}
}
});
export const { handleSetMuteOff, handleSetMuteOn } = chatSlice.actions;
export default chatSlice.reducer;
Updates Correct (The array of the user is changed from Mute 0 to Mute 1, so its a new state.
I use refresh i n extra data.
So why its not working ?
€:
Output prev/next prop:
START
Prevname: 0
Nextname: 0
START
Prevname: 1
Nextname: 1
START
Prevname: 0
Nextname: 0
START
Prevname: 0
Nextname: 0
START
Prevname: 0
Nextname: 0
START
Prevname: 0
Nextname: 0
START
Prevname: 0
Nextname: 0
START
Prevname: 1 // THAT ARE THE NEW CHANGES (SUCCESS) IT WAS Zero
Nextname: 1 // THAT ARE THE NEW CHANGES (SUCCESS) IT WAS Zero
START
Prevname: 0
Nextname: 0
START
Prevname: 0
Nextname: 0
START
Prevname: 0
Nextname: 0
START
Prevname: 0
Nextname: 0
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
