React组件传值:如何将NavBar的用户信息传递给ProductList?
如何在React组件间传递用户登录信息
要将NavBar中的用户信息传递给ProductList,有两种实用的方案可以选择:
方案1:将状态提升到公共父组件
如果NavBar和ProductList有共同的父组件(比如App.js),最直接的方式是把用户信息的状态和获取逻辑移到父组件中,再通过props传递给需要的子组件。
步骤1:修改父组件(例如App.js)
把获取用户信息的逻辑从NavBar迁移到App:
import React, { useState, useEffect } from 'react'; import NavBar from './NavBar'; import ProductList from './ProductList'; function App() { 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="app-container"> <NavBar userInfo={userInfo} /> <ProductList userInfo={userInfo} /> </div> ); } export default App;
步骤2:更新NavBar组件
移除内部的userInfo状态和getUserInfo函数,改为接收props传入的userInfo:
import React from 'react'; import { NavLink } from 'react-router-dom'; const NavBar = ({ userInfo }) => { const providers = ['twitter', 'github', 'aad']; const redirect = window.location.pathname; 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.userDetails}</p> <p>{userInfo.identityProvider}</p> </div> </div> )} </div> ); }; export default NavBar;
步骤3:在ProductList中使用用户信息
通过props接收userInfo,渲染发布者信息:
// ProductList.js import React from 'react'; const ProductList = ({ userInfo }) => { // 保留原有业务逻辑... return ( {/* 保留原有JSX结构 */} <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" /> {userInfo && <span> Posted By: {userInfo.userDetails}</span>} </footer> ); }; export default ProductList;
方案2:使用React Context API
如果组件层级较深,或者多个组件都需要访问用户信息,使用Context API可以避免props层层传递的冗余,让信息访问更高效。
步骤1:创建用户Context
新建UserContext.js文件:
import React, { createContext, useState, useEffect } from 'react'; export const UserContext = createContext(); export const UserProvider = ({ children }) => { 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 ( <UserContext.Provider value={{ userInfo }}> {children} </UserContext.Provider> ); };
步骤2:在根组件中包裹Provider
修改App.js,用UserProvider包裹整个应用:
import React from 'react'; import { UserProvider } from './UserContext'; import NavBar from './NavBar'; import ProductList from './ProductList'; function App() { return ( <UserProvider> <div className="app-container"> <NavBar /> <ProductList /> </div> </UserProvider> ); } export default App;
步骤3:在NavBar中消费Context
import React, { useContext } from 'react'; import { NavLink } from 'react-router-dom'; import { UserContext } from './UserContext'; const NavBar = () => { const { userInfo } = useContext(UserContext); const providers = ['twitter', 'github', 'aad']; const redirect = window.location.pathname; // 其余JSX代码保持不变 }; export default NavBar;
步骤4:在ProductList中消费Context
import React, { useContext } from 'react'; import { UserContext } from './UserContext'; const ProductList = () => { const { userInfo } = useContext(UserContext); // 保留原有业务逻辑... return ( {/* 保留原有JSX结构 */} <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" /> {userInfo && <span> Posted By: {userInfo.userDetails}</span>} </footer> ); }; export default ProductList;
内容的提问来源于stack exchange,提问作者Djdjsj
相关产品推荐
相关产品推荐

