I have a NavBar component which holds login information on the user. When the user is logged in it says "Welcome" along with the user details. I want to implement the same idea in another component so that when a user posts a blog, it says "Posted By: " along with the users log in details. How would I pass the details form NavBar.js to Products.js ?
import React, { useState, useEffect } from 'react';
import { NavLink } from 'react-router-dom';
const NavBar = (props) => {
const providers = ['twitter', 'github', 'aad'];
const redirect = window.location.pathname;
const [userInfo, setUserInfo] = useState();
useEffect(() => {
(async () => {
setUserInfo(await getUserInfo());
})();
}, []);
async function getUserInfo() {
try {
const response = await fetch('/.auth/me');
const payload = await response.json();
const { clientPrincipal } = payload;
return clientPrincipal;
} catch (error) {
console.error('No profile could be found');
return undefined;
}
}
return (
<div className="column is-2">
<nav className="menu">
<p className="menu-label">Menu</p>
<ul className="menu-list">
<NavLink to="/products" activeClassName="active-link">
Recipes
</NavLink>
<NavLink to="/about" activeClassName="active-link">
Help
</NavLink>
</ul>
{props.children}
</nav>
<nav className="menu auth">
<p className="menu-label">LOGIN</p>
<div className="menu-list auth">
{!userInfo &&
providers.map((provider) => (
<a key={provider} href={`/.auth/login/${provider}?post_login_redirect_uri=${redirect}`}>
{provider}
</a>
))}
{userInfo && <a href={`/.auth/logout?post_logout_redirect_uri=${redirect}`}>Logout</a>}
</div>
</nav>
{userInfo && (
<div>
<div className="user">
<p>Welcome</p>
<p>{userInfo && userInfo.userDetails}</p>
<p>{userInfo && userInfo.identityProvider}</p>
</div>
</div>
)}
</div>
);
};
export default NavBar;
This is a snippet from Products.js, where I want the user details data to be passed to:
<footer className="card-footer ">
<ButtonFooter
className="cancel-button"
iconClasses="fas fa-undo"
onClick={handleCancelProduct}
label="Cancel"
/>
<ButtonFooter
className="save-button"
iconClasses="fas fa-save"
onClick={handleSave}
label="Save"
/> Posted By: {}
</footer>
CodePudding user response:
One way is to use state variable in parent component of both footer and navbar, then passing into navbar as prop function to set the state variable to the userInfo, and in footer you can now use the userInfo
//beginning of parent component
const [userInfo, setUserInfo] = useState(null);
...
//navbar component
<NavBar setUserInfoParent={setUserInfo}/>
...
//footer component
<footer>
Posted By: {userInfo && userInfo.userDetails}
</footer>
CodePudding user response:
There will likely be many opinions on this as there are many ways to accomplish storing some Global state.
Assuming your project will be a decent size and you don't want to keep all of this data in a component and pass it down through/to each component, I would look at these few options:
- Context API: https://reactjs.org/docs/context.html
- RTK: https://redux-toolkit.js.org/tutorials/quick-start (my preference)
- And many others these days including Flux, Zustand, Mobx, Recoil...and on and on..