App.js中useEffect设置Session后子组件触发空值读取渲染错误
问题分析与解决方案
核心问题1:App组件的useEffect依赖错误 + 未清理Auth状态订阅
你在App的useEffect里把session作为依赖,这会触发无限循环:每次setSession更新状态后,useEffect会重新执行,重复调用getSession和订阅onAuthStateChange,同时初始阶段session为null的状态会传递给子组件,引发后续报错。
另外,onAuthStateChange的订阅需要在组件卸载时清理,否则会造成内存泄漏。
修改后的App组件代码:
const App = () => { const [session, setSession] = useState(null) useEffect(() => { // 初始化获取session supabase.auth.getSession() .then((response) => { setSession(response.data.session) }) // 订阅Auth状态变化,保存订阅实例用于后续清理 const authSubscription = supabase.auth.onAuthStateChange((_event, session) => { setSession(session) }) // 组件卸载时清理订阅 return () => { authSubscription.unsubscribe() } }, []) // 空数组确保该副作用只执行一次 }
核心问题2:DashboardDetails组件未处理session为null的情况
初始渲染时,session可能还未获取完成(或用户未登录),此时props.session是null,直接访问props.session.user.id必然触发类型错误。必须先判断session是否存在,再读取用户信息。
修改后的DashboardDetails组件代码:
useEffect(() => { // 先校验session存在性,再读取user.id if (props.session) { const id = props.session.user.id setId(id) } }, [props.session]) // 不要用props作为依赖,精准依赖session即可
额外优化:PrivateRoute的权限控制
既然是私有路由,建议在PrivateRoute内部直接判断session是否有效,不存在时跳转登录页,从根源避免子组件接收到null的session:
const PrivateRoute = ({ children, session }) => { if (!session) { return <Navigate to="/login" replace /> } return children }
内容的提问来源于stack exchange,提问作者Jon Nicholson
相关产品推荐
相关产品推荐

