I'm using functional ponent in React and i'm trying to reload the ponent after button is clicked.
import { useCallback, useState } from 'react';
const ProfileLayout = () => {
const [reload, setReload] = useState(false);
const onButtonClick = useCallback(() => {
setReload(true);
}, []);
return (
{reload && (
<ProfileDetails />
)}
<Button onClick={onButtonClick} />
);
};
export default ProfileLayout;
I'm not able to see again the ponent after page loaded.
Note: I don't want to use window.location.reload();
I'm using functional ponent in React and i'm trying to reload the ponent after button is clicked.
import { useCallback, useState } from 'react';
const ProfileLayout = () => {
const [reload, setReload] = useState(false);
const onButtonClick = useCallback(() => {
setReload(true);
}, []);
return (
{reload && (
<ProfileDetails />
)}
<Button onClick={onButtonClick} />
);
};
export default ProfileLayout;
I'm not able to see again the ponent after page loaded.
Note: I don't want to use window.location.reload();
- Please provide a minimal reproducible example. We should be able to copy/paste the code and run it ourselves without any errors. – Code-Apprentice Commented Apr 22, 2020 at 14:52
- I have updated my code. – alar Commented Apr 22, 2020 at 14:57
-
I still can't reproduce the behavior you are asking about because
ProfileDetails
is missing. – Code-Apprentice Commented Apr 22, 2020 at 15:01
4 Answers
Reset to default 1Note: I don't want to use
window.location.reload();
That is good because that is not the correct way to do this in React. Forcing the browser to reload will lose all of your ponent or global state.
The correct way to force a ponent to render is to call this.setState()
or call this.forceUpdate()
.
What do you mean by reloading the ponent? You want to re-render it or you want to make the ponent fetch the data again? Like "refresh"?
Anyways the way your ponent is coded the <ProfileDetails />
ponent will not show up on the first render since you are doing reload && <ProfileDetails />
, but reload
is initially false. When you click the button then ProfileDetails will appear, but another click on the button won't have any effect since reload
is already set to true
.
If you want to refresh the data the ponent uses, then you need to implement a callback that triggers the data fetching.
Edit after clarification by author
const ProfileContainer = (props) => {
// initialProfile is the profile data that you need for your ponent. If it came from another ponent, then you can set it when the state is first initialized.
const [ profile, setProfile ] = useState(props.initialProfile);
const loadProfile = useCallback( async () => {
// fetch data from server
const p = await fetch('yourapi./profile'); // example
setProfile(p);
}
return (<><ProfileDetails profile={profile} /> <button onClick={loadProfile} /></>)
}
Alternate approach to load the data within the ponent
const ProfileContainer = (props) => {
const [ profile, setProfile ] = useState(null);
const loadProfile = useCallback( async () => {
// fetch data from server
const p = await fetch('yourapi./profile'); // example
setProfile(p);
}
useEffect(() => loadProfile(), []); // Empty dependency so the effect only runs once when ponent loads.
return (<>
{ /* needed since profile is initially null */
profile && <ProfileDetails profile={profile} />
}
<button onClick={loadProfile} />
</>);
};
const ProfileLayout = () => {
const [reload, setReload] = useState(0);
const onButtonClick = useCallback(() => {
setReload(p => p+1);
}, []);
return (
{Boolean(reload) && (
<ProfileDetails />
)}
);
};
If you need to force the refresh, then better use a number than a boolean.
const ProfileLayout = () => {
const [reload, setReload] = useState(0);
const onButtonClick = useCallback(() => {
setReload(p => p+1);
}, []);
return (
{Boolean(reload) && (
<ProfileDetails />
)}
);
};