I'm passing objects down to memo child components and i want define the condition when the child component should be rerenderd. If i set the condition to always rerender, it works but it rerenders to often which causes other problems what i dont want either.
My data model (simplified):
A1
├── B1
│ ├── loading : false
├── B2
│ ├── loading : true
├── B3
│ ├── loading : false
A2
├── B1
│ ├── loading : false
├── B2
│ ├── loading : true
├── B3
│ ├── loading : false
...
...
I want to show a loading icon if loading attribute is true
The component model:
AComponent:
function AComponent(props: any) {
let dataChangeSubscription: Subscription;
const [dataContainer, _setDataContainer] = useState<DataContainerType | null>(null);
const dataContainerRef = useRef(dataContainer);
function setDataContainer(dataContainerChunk: DataContainerType) {
dataContainerRef.current = dataContainerChunk;
_setDataContainer(dataContainerChunk);
}
useEffect( () => {
initDataChangeSubscription();
return () => {
dataChangeSubscription.unsubscribe();
}
}, [])
const initDataChangeSubscription= (): void => {
dataChangeSubscription= service.getDataChangedEvent().subscribe( data => {
if(data != null) {
data.map( (dataChunk) => {
if (dataChunk.name === dataContainerRef.current?.name) {
setDataContainer({...dataChunk});
}
})
}
} )
}
return(
<>
<div>
{
dataContainer?.map((b: BType, index: number) => (
<MemoizedBComponent b={b} />
))
}
</div>
</>
)
}
BComponent:
function BComponent(props: any) {
return (
<>
<div>
{props.b.loading}
</div>
</>
)
}
export default BComponent;
function propsAreEquals(prevState: any, nextState: any) {
if (prevState.b.loading !== nextState.b.loading) {
return false;
}
return true;
}
export const MemoizedBComponent = React.memo(BComponent, propsAreEquals);
Problem: The dataChangeEvent gets triggered twice, the first time it sets the loading attribute to true and the second time to false. The propsAreEquals Method of BComponent gets calles twice but the loading attribute of prevState and nextState is always equal. First call both attributes are true and second call both are false. So if i compare the attributes like in the code snippet above the rerender will not get triggered. What am i doing wrong here?
(I found a similar question here React.memo always contains the same value on prevProps and nextProps but i think the problem had a different origin than mine)