React+Firebase项目中如何将TopBar.js的user对象传递到App.js及其他组件
解决方案
前置修复:解决现有useEffect死循环问题
你当前的useEffect依赖数组包含user,每次执行setUser都会触发useEffect重新运行、重复注册监听,先把依赖里的user删除,只保留userName即可。
方案1:状态提升(适合小型项目)
直接把user状态和auth监听逻辑从TopBar.js移到公共父组件App.js中,再通过props向下传递给需要的组件即可。
App.js示例代码
import { useState, useEffect } from 'react'; import TopBar from './TopBar'; import Create from './Create'; import { auth } from './你的firebase配置文件路径'; function App() { const [user, setUser] = useState(null); const [userName, setUserName] = useState(''); // 自行补充userName的赋值逻辑 useEffect(() => { const unsubscribe = auth.onAuthStateChanged((authUser) => { if (authUser) { setUser(authUser) if(!authUser.displayName){ authUser.updateProfile({ displayName : userName }); } } else { setUser(null); } }) return () => unsubscribe(); }, [userName]); return ( <div className="App"> {/* 把user传给TopBar做身份认证逻辑/展示 */} <TopBar user={user} /> {/* 把user传给Create组件做数据库写入用 */} <Create user={user} /> {/* 其他业务组件 */} </div> ) } export default App;
之后你在TopBar.js和Create.js中直接通过props接收user即可使用。
方案2:React Context(适合中大型项目,避免props层层透传)
如果你的组件嵌套层级深,层层传props维护成本高,可以用Context做全局身份状态管理。
步骤1:创建全局身份上下文
新建AuthContext.js文件:
import { createContext, useContext, useState, useEffect } from 'react'; import { auth } from './你的firebase配置文件路径'; const AuthContext = createContext(); export function AuthProvider({ children }) { const [user, setUser] = useState(null); const [userName, setUserName] = useState(''); // 自行补充userName的赋值逻辑 useEffect(() => { const unsubscribe = auth.onAuthStateChanged((authUser) => { if (authUser) { setUser(authUser) if(!authUser.displayName){ authUser.updateProfile({ displayName : userName }); } } else { setUser(null); } }) return () => unsubscribe(); }, [userName]); return ( <AuthContext.Provider value={{ user }}> {children} </AuthContext.Provider> ) } // 封装自定义Hook简化调用 export function useAuth() { return useContext(AuthContext); }
步骤2:全局注册上下文
修改入口文件index.js,把App组件包裹在AuthProvider中:
import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './App'; import { AuthProvider } from './AuthContext'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <AuthProvider> <App /> </AuthProvider> </React.StrictMode> );
步骤3:任意组件直接获取user
比如在TopBar.js中:
import { useAuth } from './AuthContext'; function TopBar() { const { user } = useAuth(); // 原有TopBar逻辑,直接使用user即可 }
在Create.js中同理:
import { useAuth } from './AuthContext'; function Create() { const { user } = useAuth(); // 写入数据库时直接取user的uid、displayName等字段即可 }
内容的提问来源于stack exchange,提问作者Tushar
相关产品推荐
相关产品推荐

