You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中useEffect触发元素类型无效错误排查求助

问题描述

加载代码时触发如下错误:

Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports. Check the render method of "Page".

代码如下:

import {Stack, useRouter} from "expo-router";
import {Card, Menu, Text} from "@ui-kitten/components";
import {AuthService} from "../services/AuthService";
import {useEffect, useState} from "react";

export default function Page() {
const router = useRouter();

const [auth, setAuth] = useState(null);
const [companies, setCompanies] = useState([]);
const [activeCompany, setActiveCompany] = useState(null);

useEffect(() => {
    AuthService.getAuth().then(tempAuth => {
        setAuth(tempAuth);

        if (tempAuth !== null) {
            setCompanies(tempAuth.companies)

            AuthService.getActiveCompany().then(activeCompany => {
                    console.log(activeCompany, 'active company')
                    setActiveCompany(activeCompany);
                }
            )
        }
    })
}, [])

return (
    <>
        <Stack.Screen
            options={{
                title: activeCompany === null ? 'Choose company' : activeCompany.name,
                headerBackVisible: false
            }}/>
    </>
)
}

控制台打印显示company变量不为空,尝试硬编码setActiveCompany({id: 'test'});仍出现相同错误,请问哪里操作有误?


问题原因与解决方法

错误根源

你在页面组件的return中直接渲染Stack.Screen,这违反了expo-router的使用规则。Stack.Screen是用于在路由布局文件(如_layout.js)中定义路由栈配置的元素,不能作为页面组件的可渲染内容直接返回,这才是导致"组件类型无效"错误的核心原因,和useEffect里的状态更新逻辑无关。

解决步骤

  1. 移除页面中的Stack.Screen:页面组件的return必须返回实际可渲染的UI元素(比如文本、容器、卡片等),不能仅保留Stack.Screen。
  2. 动态设置Header选项:如果需要根据activeCompany动态修改页面标题等Header配置,使用useLayoutEffect结合router.setParams实现。

修改后的代码示例:

import {Stack, useRouter, useLayoutEffect} from "expo-router";
import {Card, Menu, Text, View} from "@ui-kitten/components";
import {AuthService} from "../services/AuthService";
import {useEffect, useState} from "react";

export default function Page() {
const router = useRouter();

const [auth, setAuth] = useState(null);
const [companies, setCompanies] = useState([]);
const [activeCompany, setActiveCompany] = useState(null);

useEffect(() => {
    AuthService.getAuth().then(tempAuth => {
        setAuth(tempAuth);

        if (tempAuth !== null) {
            setCompanies(tempAuth.companies)

            AuthService.getActiveCompany().then(activeCompany => {
                    console.log(activeCompany, 'active company')
                    setActiveCompany(activeCompany);
                }
            )
        }
    })
}, [])

// 动态设置Header参数
useLayoutEffect(() => {
    router.setParams({
        title: activeCompany === null ? 'Choose company' : activeCompany.name,
        headerBackVisible: false
    });
}, [activeCompany]);

return (
    {/* 这里放页面实际需要展示的UI内容 */}
    <View style={{flex: 1, padding: 16}}>
        <Text>{activeCompany ? `当前公司:${activeCompany.name}` : '请选择公司'}</Text>
        {/* 可以添加公司选择的UI组件,比如列表、菜单等 */}
    </View>
)
}

补充说明

确保你的路由布局文件(如app/_layout.js)已经正确配置了Stack容器,示例如下:

import { Stack } from 'expo-router';

export default function RootLayout() {
  return (
    <Stack>
      {/* 这里定义各个路由的默认配置 */}
      <Stack.Screen name="index" options={{ title: '首页' }} />
      <Stack.Screen name="page" /> {/* 你的Page页面路由 */}
    </Stack>
  );
}

内容的提问来源于stack exchange,提问作者Mikkel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 05:30:01