React项目中user_id可渲染但控制台为undefined、ID比对失效如何解决?
问题原因
- 类组件实例属性未同步props更新:你在
AddRemoveLayout的constructor中仅执行了一次this.user_id = props.user_id赋值,constructor只会在组件初始化时运行一次。而Auth0的useUser()返回的用户信息是异步加载的,首次渲染时用户认证还未完成,user.sub为undefined,此时constructor会把this.user_id初始化为undefined。后续Auth0加载完成、props.user_id更新时,constructor不会重新执行,this.user_id永远保留初始的undefined值,所以控制台打印、条件判断拿到的都是undefined。
- 类组件实例属性未同步props更新:你在
- 缺少加载状态判断:没有对Auth0的用户加载状态做拦截,首次渲染时必然会拿到
undefined的用户ID。
- 缺少加载状态判断:没有对Auth0的用户加载状态做拦截,首次渲染时必然会拿到
- (可选排查)函数命名大小写不匹配:你定义的卡片组件函数名为小写开头的
all_Cards,但在类组件中绑定的是大写开头的AllCards,如果导入时存在大小写错误也可能导致参数传递异常。
- (可选排查)函数命名大小写不匹配:你定义的卡片组件函数名为小写开头的
解决方法
步骤1:移除类组件中对props的冗余赋值
不要把props存储到类的实例属性中,直接在使用时读取最新的this.props即可,修改AddRemoveLayout相关代码:
constructor(props) { super(props); this.widgets = props.widgets; // 删掉this.user_id = props.user_id这行 this.onBreakpointChange = this.onBreakpointChange.bind(this); this.AllCards = AllCards.bind(this) } render() { return ( <div> <ResponsiveReactGridLayout onLayoutChange={this.onCustomLayoutChange} onBreakpointChange={this.onBreakpointChange} {...this.props} > {this.widgets?.map((widget) => // 直接读取props.user_id,永远拿到最新值 this.AllCards(widget, this.props.user_id) )} </ResponsiveReactGridLayout> </div> ); }
步骤2:添加Auth0加载状态拦截
在Body_m组件中使用useUser返回的isLoading状态,等用户信息加载完成后再渲染后续组件,避免初始undefined问题:
export default function Body_m(props){ // 取出useUser返回的加载状态 const {user, isLoading} = useUser(); const widgets = props.widgets; // 加载中返回占位提示 if(isLoading) return <div>认证信息加载中...</div> const user_id = user?.sub; return ( <main> <AddRemoveLayout widgets={widgets} user_id={user_id}/> </main> ) }
步骤3:(可选)统一函数命名规范
确保卡片函数的导入、绑定、调用的名称大小写完全一致,避免引用错误。
内容的提问来源于stack exchange,提问作者Martin SAISON
相关产品推荐
相关产品推荐

