1
votes

I'm trying to render actual data in child component, but data does not render. What is wrong?

Parent component

const UserPanelContainer = ({ currentUser }) => {
  

const [initUsersData, setinitUsersData] = useState(currentUser);

  useEffect(() => {
    console.log('useEffect')
    setinitUsersData(()=>getnewData())
  }, [setinitUsersData, currentUser])

const getnewData = () =>{
  console.log('getnewData')
  setinitUsersData(currentUser)
}

  return (
    
  <UserPanel currentUser={initUsersData} hanleOnClickOut={hanleOnClickOut} >{console.log('usepanContainerRender')}</UserPanel>
    
  );
};

export default UserPanelContainer;

child

    const UserPanel = ({ currentUser, hanleOnClickOut }) => {
    
    console.log(currentUser);
  return (
     <div className="dropdown">
        {console.log('userPanelRender')}
      <button
        className="btn btn-secondary dropdown-toggle"
        type="button"
        id="dropdownMenuButton"
        data-toggle="dropdown"
        aria-haspopup="true"
        aria-expanded="false"
      >
        <img
          className="avatar"
          src={currentUser.photoURL}
          alt="avatar"
        />
        {currentUser.displayName}
      </button>
      <div className="dropdown-menu" aria-labelledby="dropdownMenuButton">
        <div className="dropdown-item">
          Вошел как {currentUser.displayName}
        </div>
        <div className="dropdown-item" onClick={hanleOnClickOut}>
          Выйти
        </div>
      </div>
    </div>
  );
};

export default UserPanel;

In console in child I can see correct actual data in props, but they are not rendered. Actual data contains "currentUser" prop. But on Browser page i cant see data.... (if i delete currentUser from useEffect depencity i can see data from previus API call)

3
Children don't update when their props change. You have to use their state. Add the props data in state and change the state when needed, this will update the component - gpopides
What did you get in child component when you console it ? - Garsivirus
@Woops they actually do rerender when props change - Garsivirus
@ Woops if you mean like this - dont work also const [initUsersDatainChild, setinitUsersDatainChild] = useState(''); useEffect(() => { console.log('useEffect') setinitUsersDatainChild(currentUser) }, [ currentUser]) - dmitry
@Garsivirus - i got actual data for render - dmitry

3 Answers

0
votes

I see you are passing the setinitUsersData in the useEffect dependency array whereas you need to pass the actual state variable

try this,

useEffect(() => {
    ...
  }, [initUsersData, currentUser])

instead of current,

useEffect(() => {
    ...
  }, [setinitUsersData, currentUser])
0
votes

I think by actual data you mean some api response.

Try this :-

useEffect(() => {
    console.log('useEffect')
    getnewData(currentUser)
  }, [currentUser])

const getnewData = (currentUser) =>{
  console.log('getnewData')
  axios.get("/pathToData").then((res) => {
   console.log(res);
   setinitUsersData(res);
  })

}
0
votes

Replace parent component with the following code. You don't need to use useEffect as per the code you've posted. Since parent is already receiving currentUser and you have already updated state with that

const UserPanelContainer = ({ currentUser }) => {
  const [initUsersData, setinitUsersData] = useState(currentUser);
  return (<UserPanel 
   currentUser={initUsersData} 
   hanleOnClickOut={hanleOnClickOut}>{console.log('usepanContainerRender')}</UserPanel>
  );
};

export default UserPanelContainer;