【问题标题】:React. Error: Element type is invalid: expected a string or class/function but got: object做出反应。错误:元素类型无效:应为字符串或类/函数,但得到:对象
【发布时间】:2021-03-02 03:42:40
【问题描述】:

我对 react/js 很陌生,所以我希望我在这里完全错误地使用 useEffect,但是如果有人给我指出正确的方向,那就太好了:)。

我正在尝试编写的代码是根据用户登录时选择的角色将元素设置为名为 HomeScreen 的 const。

function WorkflowTemplate({ Logout }) {
const user = useContext(userContext);

const [HomeScreen, setHomeScreen] = useState();

useEffect(() => {
    console.log("starting useEffect role select");
    switch (user.role) {
        case "Chemistry":
            return setHomeScreen(<WFChemistry />), console.log(HomeScreen);
        case "Micro":
            return setHomeScreen(<WFMicro />), console.log(HomeScreen);
        case "Manager":
            return setHomeScreen(<WFManager />);
        case "Sample admin":
            return setHomeScreen(<WFSampleAdmin />);
        case "Developer":
            return setHomeScreen(<WFDev />);
        default:
            console.log("error with role select");
    }
});

上面的代码返回错误:元素类型无效:期望字符串(对于内置组件)或类/函数(对于复合组件),但得到:对象。

检查Router.Consumer的渲染方法。

但是,在尝试实现 useEffect 之前,我有

function WorkflowTemplate({ Logout }) {
const user = useContext(userContext);
const HomeScreen = () => {
    console.log("running HomeScreen function");
    switch (user.role) {
        case "Chemistry":
            return <WFChemistry />;
        case "Micro":
            return <WFMicro />;
        case "Manager":
            return <WFManager />;
        case "Sample admin":
            return <WFSampleAdmin />;
        case "Developer":
            return <WFDev />;
        default:
            return console.log("error with role switch");
    }
} 

这工作正常,预计每次渲染组件时都会调用它,这是不可取的。

我在使用 useEffect 函数时做错了什么?

提前谢谢你,

格雷格

【问题讨论】:

  • 在第二种情况下 HomeScreen 是一个可调用函数。在第一种情况下,您已经调用了组件,它只是一个 JSX 元素。所以你需要将它渲染为 {HomeScreen} 而不是

标签: javascript reactjs


【解决方案1】:

尝试为您的状态添加一个初始值(例如:null),例如:const [HomeScreen, setHomeScreen] = useState(null)

如果您不希望您的组件每次都渲染,那么您可以在 useEffect 中传递一个空数组,这意味着只渲染一次:

useEffect(() => {
    console.log("starting useEffect role select");
    switch (user.role) {
        case "Chemistry":
            return setHomeScreen(<WFChemistry />), console.log(HomeScreen);
        case "Micro":
            return setHomeScreen(<WFMicro />), console.log(HomeScreen);
        case "Manager":
            return setHomeScreen(<WFManager />);
        case "Sample admin":
            return setHomeScreen(<WFSampleAdmin />);
        case "Developer":
            return setHomeScreen(<WFDev />);
        default:
            console.log("error with role select");
    }
}, []);

【讨论】:

    【解决方案2】:

    Component&lt;Component/&gt;

    组件本身与调用它返回的 JSX 元素之间存在差异 &lt;Component/&gt; 在您的第一个代码中,您的 HomeScreen 变量的值是 JSX 元素,因此您不需要再次调用它。你只需要像这样渲染它:

    <SomeParent>
       {HomeScreen}
    </SomeParent>
    

    当您尝试将其称为 &lt;HomeScreen/&gt; 时,您将收到您发布的错误。

    在您的第二个示例中,HomeScreen 是一个函数,因此可以调用 &lt;HomeScreen/&gt;。您实际上是在组件中创建一个功能组件。你说得对,这对性能不利。

    你的useEffect 并没有更好,因为它没有依赖关系,所以它会在每次渲染时重新运行。它应该依赖于user.role

    【讨论】:

    • 您好,感谢您的信息。稍后在代码中,我使用 作为导航的一部分,在这里我将组件呈现为 {HomeScreen}。我可以使用上面的开关将 HomeScreen 设置为组件吗?我不确定如何执行此操作的语法?感谢您提醒我关于 useEffect 的第二个参数 :) 编辑:控制台在通过开关时将 HomeScreen 读出为未定义,所以我假设我没有将它正确设置为组件?我试过 setHomeScreen({component}) 但这也没有用
    猜你喜欢
    • 2020-07-18
    • 1970-01-01
    • 1970-01-01
    • 2020-08-09
    • 2021-10-24
    • 2020-05-23
    • 2017-06-10
    • 2020-11-11
    • 1970-01-01
    相关资源
    最近更新 更多