I have a component that renders a child that when it's called from within another component, continuously unmount and remounts. I can't figure out why this is.
The code looks roughly like this:
import React, { useState } from 'react';
import { View } from 'react-native';
import EditLayout from './EditLayout'
export default users = (props) => {
let { user } = props
const [layout, setLayout] = useState([])
const [layout, setLayout] = useState([])
const Header = () => {
return (<View>
<EditLayout layout={layout} user={user} />
</View>
)
}
return (
<View style={{ flex: 1 }}>
{/* <EditLayout layout={layout} user={user} /> */}
<Header />
</View>
);
}
And as-is this causes many re-renders of EditLayout (EditLayout is very minimal).
And when I swap the commented out code above where it says {/* <EditLayout ... /> /} to instead be {/ */}, then the remounts go away. It seems for some reason when called inside Header, it causes many un & remounts before finally settling down.
Any idea what may be causing this?
Edit: EditLayout and output
This is the relevant EditLayout code, even with just this below, I can replicate the issue (so it doesn’t have seem to have to do with the rest of the EditLayout code).
Here, I’m setting checkStateData to a default “Mounted Edit Layout” and changing it to false right away, only printing when it it’s true.
export default EditLayout = (props) => {
const [checkStateData, setCheckStateData] = useState("Mounted Edit Layout")
checkStateData && console.log("*****", checkStateData) // Print the current status
useEffect(() => {
if(setCheckStateData){
console.log("Made it here")
setCheckStateData(false)
}
}, [])
return (
<View style={{ flex: 1 }}>
{/* {headerLayoutData && headerLayoutData.map((card, i) => {
if (card && user){
return <Card card={card} key={i} user={user} />
}
})}
{newCards && newCards.map((card, i) => {
return <NewCard key={i} user={user} />
})} */}
</View>
);
}
Via <Header />
[Tue Feb 23 2021 15:43:11.836] LOG ***** Mounted Edit Layout
[Tue Feb 23 2021 15:43:11.853] LOG Made it here
[Tue Feb 23 2021 15:43:12.127] LOG ***** Mounted Edit Layout
[Tue Feb 23 2021 15:43:12.172] LOG Made it here
[Tue Feb 23 2021 15:43:12.179] LOG ***** Mounted Edit Layout
[Tue Feb 23 2021 15:43:12.259] LOG Made it here
[Tue Feb 23 2021 15:43:12.281] LOG ***** Mounted Edit Layout
[Tue Feb 23 2021 15:43:12.300] LOG Made it here
[Tue Feb 23 2021 15:43:12.303] LOG ***** Mounted Edit Layout
[Tue Feb 23 2021 15:43:12.307] LOG Made it here
[Tue Feb 23 2021 15:43:12.309] LOG ***** Mounted Edit Layout
[Tue Feb 23 2021 15:43:12.314] LOG Made it here
[Tue Feb 23 2021 15:43:12.364] LOG ***** Mounted Edit Layout
[Tue Feb 23 2021 15:43:12.373] LOG Made it here
[Tue Feb 23 2021 15:43:12.373] LOG ***** Mounted Edit Layout
[Tue Feb 23 2021 15:43:12.384] LOG Made it here
Without <Header>
[Tue Feb 23 2021 15:43:32.797] LOG ***** Mounted Edit Layout
[Tue Feb 23 2021 15:43:32.856] LOG Made it here
In your current code, Header
(a component) is recreated each time Users
component is rerendered. This will lead to bugs because you don't want to recreate a child component (instead it maybe rerendered when needed).
And to prevent this, you should define Header
outside parent component i.e. Users
(Name should start with Upper Case).
So, Header
can be in a different file or in same file (but outside Users
). If Header
is going to be a large component, it is good to keep it in a different file.
// Don't do this
function MainComp() {
//...
function ChildComp() {
// ...
}
}
// Do this instead
function MainComp() {
// ...
}
function ChildComp() {
// ...
}