'Unusual Render and Re-renders of the child and parent component causing layout flicker
I am trying to make a dashboard for teachers where the details of the teachers would be displayed. I am using nested routing to display the components related to the teacher's dashboard and therefore I have sidebar too. I was facing a flicker in the layout of the side bar while navigating from one route to another about which i have mentioned in my another question How stop the flicker in the SideNav caused by the useEffect which fetches some data on every render - Reactjs. So I was playing with code and did some console logs to track exactly what is happening to the component and found out that there is a unusual rendering of the components. I am making an api call inside the useEffect of the parent and do not know if thats causing an issue. Below is all the codes of the parent and child
Dashboard (Parent Component)
const TeacherDashboard = () => {
// selecting slices for getting user data
const { authTokens, user } = useSelector((state) => state.login);
// setting states
const [teacher, setTeacher] = useState(null); //to store the teacher detail
const [loading, setLoading] = useState(true);
useEffect(() => {
// setting the loading tru to wait for the data
setLoading(true);
/*
this is the procedure to retrive data from an async api call because we
cannot directly use async calls so we have to wrap them inside another small function.
*/
const fectData = async () => {
//await here is neccessary to wait for the promise to get resolved
let response = await fetchTeacherDetail(user.user_id);
setTeacher(response.data);
setLoading(false);
};
fectData();
}, []);
console.log("Rendered Dashboard");
return (
<Container>
<SideBar name={!loading && teacher.name} />
<ContentMainContainer>
{/* this makes the nested routes display here */}
<Outlet />
</ContentMainContainer>
</Container>
);
};
SideBar (Child Component)
const SideBar = (props) => {
// selecting slices for getting user data
const { authTokens, user } = useSelector((state) => state.login);
// setting states
const [teacher, setTeacher] = useState(null); //to store the teacher detail
const [loading, setLoading] = useState(true);
console.log("The SideBar has rendered");
const profileButton = (
<Fragment>
<NavLink activeclassname="acitve" to="/teacher/profile">
<i className="fas fa-user"></i>Profile
</NavLink>
</Fragment>
);
const enterDetails = (
<Fragment>
<NavLink activeclassname="acitve" to="/teacher/profile">
<i className="fas fa-pen"></i> Enter Details
</NavLink>
</Fragment>
);
return (
<SideNav>
<UserNameContainer>
<p>{props.name}</p>
</UserNameContainer>
<ButtonContainer>
{/* <Fragment>
{!loading && teacher.is_verified ? profileButton : enterDetails}
</Fragment> */}
<NavLink activeclassname="acitve" to="info">
<i className="fas fa-info-circle"></i> My Information
</NavLink>
<NavLink activeclassname="acitve" to="student-requests">
<i className="fas fa-user-plus"></i> Requests
</NavLink>
<NavLink activeclassname="acitve" to="enrolled-student">
<i className="fas fa-user-graduate"></i> My Students
</NavLink>
<NavLink activeclassname="acitve" to="payment">
<i className="fas fa-rupee-sign"></i> Payments
</NavLink>
</ButtonContainer>
</SideNav>
);
};
export default memo(SideBar);
And now the Console Logs about how the components are rendering
on first load after login in
Rendered Dashboard
SideBar.js:16 The SideBar has rendered
TeacherDashboard.js:35 use effect called
TeacherDashboard.js:38 Rendered Dashboard
TeacherDashboard.js:38 Rendered Dashboard
SideBar.js:16 The SideBar has rendered
next on clicking on any link to route to one of the nested route
Rendered Dashboard
SideBar.js:16 The SideBar has rendered
TeacherDashboard.js:35 use effect called
TeacherDashboard.js:38 Rendered Dashboard
TeacherDashboard.js:38 Rendered Dashboard
SideBar.js:16 The SideBar has rendered
on the third click
Rendered Dashboard
SideBar.js:16 The SideBar has rendered
TeacherDashboard.js:38 Rendered Dashboard
SideBar.js:16 The SideBar has rendered
TeacherDashboard.js:35 use effect called
TeacherDashboard.js:38 Rendered Dashboard
TeacherDashboard.js:38 Rendered Dashboard
SideBar.js:16 The SideBar has rendered
the components are getting rendered in this pattern. Please help me to rectify this problem of unusual re-rendering and eventually stop the flicker. I am new to react do not understand how to solve it
The Flickering Problem on the side bar
Solution 1:[1]
Every time you trigger the useEffect in the parent, you set the loading state to true. This will cause the name prop you send to the SideBar to toggle between a string and false/undefined, which will trigger a re-render in the Sidebar
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Gøran Cantona |

