so I have this parent component that has a child component. I’ve defined a route for this component in the main app. now i want to access this parent from another page, so i’ve used the Link component. The issue is that whenever a user wants to access the page (parent component), the useEffect in the child does not run whatsoever, and as a result an error is thrown. here is the relevant code.
the app component:
import { BrowserRouter, Routes, Route} from "react-router-dom";
import Signup from "./components/signup";
import Messenger from "./components/messenger";
import Login from "./components/login";
function App() {
return (
<>
<Routes>
<Route path="/" element={<Login/>}/>
<Route path='/signup' element={<Signup />}/>
<Route path='/messenger' element={<Messenger/>}/>
</Routes>
</>
);
}
export default App;
the component wherefrom i want to call the parent
import { useEffect, useState, useRef } from 'react';
import {Link } from 'react-router-dom';
import SendIcon from '@mui/icons-material/Send';
import CircleIcon from '@mui/icons-material/Circle';
import AccountCircleIcon from '@mui/icons-material/AccountCircle';
const Header = ({pfp}) => {
return (
<div className='header'>
<div className='headerleft'>
<img src={logo} className='logo' alt="" />
</div>
<div className='headerright'>
{ismsg && <span className={textval < 10 ? "countertexts" : "countertextsdouble"} >8</span>}
<Link to="/messenger"><SendIcon className='texts' fontSize='large' /></Link>
</div>
</div>
);
}
export default Header;
the parent
return (
<>
conversations.map((c) => (
<div key={c._id} onClick={() => { convohandler(c) }}>
<Conversation conver={c} latestchat={latestchat} />
</div>
))
</>
);
}
export default Messenger;
the child
import { useSelector } from "react-redux";
import { useEffect, useState} from "react";
const Conversation = ({conver,latestchat}) => {
console.log(conver) // this prop sent from the parent is getting printed just fine.
let [fre, setFre] = useState("");
let [isnow, setIsnow] = useState(false);
useEffect(() => {
console.log("not working anymore"); // this text is never printed
// api call to set 'fre' state value
},[]);
return (
<div className={ fre.blocked.includes("user") ? "blocked" : "unblocked" }>
);
}
export default Conversation;
the error arises due to the initial state value being empty. but that is not the solution.
i want to use the api call to set the state value, which apparently is impossible because the useEffect doesnt run. could anyone please help me with this. i think the issue arises from the usage of the link component. but i’m not sure.
thank you
2
Answers
React unmounts the component when the new component is rendered.
You said you state is empty so it means the route here is unMounted.(You cannot run useEffect in unmounted route right?!).
If you want to render the component with the data, you have to send the data to child from parent. It means you can use data fetch in parent using useEffect and send it to child component in this case,
Messenger
toConversation
.Try updating your child component code –
The issue is that the state is empty as you mentioned. What is happening here is that return executes first then useEffect. At this time it gets empty state, thus blocked is undefined hence includes on undefined throws error.
Resolution – We have used optional chaining here, which is equal to using –