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

React中'type is invalid'错误排查求助

排查React组件渲染错误:type is invalid问题

错误信息

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 'MoviesCouch'at createAndFibersFromTypeProps,
createFiberFromElement,
reconcileSingleElement,
reconcileChildFibers,
reconcileChild,
updateHostComponent,
beginWork ,
 HTMLUnknownElement.callCallback,
Object.invokeGuardedCallbackDev,
nvokeGuardedCallback,
beginWork$1,
performUnitOfWork,
workLoopSync,
at renderRootSync,
at performConcurrentWorkOnRoot, 
at workLoop ,
at flushWork ,
at MessagePort.performWorkUntilDeadline 
or this message
Warning: React.jsx: 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.

相关代码

import  {React, useEffect, useState} from "react"; 
import { Col, Row}  from "react-bootstrap";
import { Container } from "react-bootstrap";
import { toast } from "react-bootstrap";
import PropTypes from "prop-types";

import FavoriteMovies from "./favorite-movies";
import UserInfo  from "./user-info";
import UpdateView from "./update-user";
import DeleteUser from "./delete-user";


export const TestProfile= ({user, setUser, movies, token, updateUser}) => {
    
    const [myUser, setMyUser] = useState("");
    const [username, setUsername] = useState("");
    const [password, setPassword] = useState("");
    const [email, setEmail] = useState("");
    const [birthday, setBirthday] = useState("");

    //get users 
useEffect(() => {
    const token = window.localStorage.getItem("token");
    fetch(`https://movies-couch-api.vercel.app/users/${user.Username}`,
    {
        method: "GET",
        headers: { Authorization: `Bearer ${token}` } })
        .then((response) => {
            if (response.ok) {
                console.log("User data retrieved")
            } else {
                console.log("User data coudl not be retrieved.")
            }
            setMyUser(response.data);
            console.log(response);
    })
        .catch((error) => {
        console.error("An error ocurred" + error);
        });
}, []);

// let moviesId = movies_.id -> ?
// Fav-movies 
// const favoriteMovies = movies.filter((movie) => favoriteMovies.includes(movie._id))     

// remove-fav_Movies
 removeFavMovie = async (movies) => {
   const user = localStorage.getItem("user");
   console.log(user);
   const token = localStorage.getItem("token");
   console.log(token);
   fetch(`https://movies-couch-api.vercel.app/users/${user.Username}/movies/${movies._id}`,
   {
     method: "DELETE",
    header: {Authorization: `Bearer ${token}`}}
   ) 
   .then((response) => {
       console.log(response);
       toast.success(`The Movie: ${movies._id} was removed from Favorite List`)
   })
   .catch(function (error) {
       console.error(" An error ocurred" +error);
   })
}

console.log(useEffect);
console.log(updateUser);
return (
    <Container className="profile-view">
            <Row className="d-flex justify-content-center p-4">
                <Col >
                    <UserInfo user={user}/>
                </Col>
                </Row> 
               <Row className="d-flex justify-content-center p-4">
                    <Col >
                        <UpdateView user={user} updateUser={updateUser}/>
                    </Col>
                </Row>
                <Row>
                    <Col>
                        <FavoriteMovies />
                    </Col>
                </Row>
                <Row className="d-flex justify-content-center p-4">
                    <Col>
                        <DeleteUser user={user}/>
                    </Col>
                </Row>
        </Container>
    ); 
};


TestProfile.propTypes = {
    user: PropTypes.object,
    movies: PropTypes.object, 
    token: PropTypes.number,
    updateUser: PropTypes.func,
    removeFavMovie: PropTypes.func
}

错误原因分析

  1. 子组件导入导出不匹配:错误提示明确指向组件导入/导出问题。当前代码使用默认导入(如import UserInfo from "./user-info"),但如果对应的子组件是命名导出(如export const UserInfo = () => {}),会导致导入的组件为undefined,最终触发渲染错误。

  2. react-bootstrap toast 导入错误:react-bootstrap 中没有名为toast的函数导出,你使用的toast.success是react-toastify库的API,当前导入会导致toast为undefined,虽不是直接触发组件类型错误,但会引发后续执行错误。

  3. 函数组件内方法定义语法错误:removeFavMovie = async (movies) => {}是类组件的方法定义语法,在函数组件中必须使用const声明变量来定义函数,否则会引发语法错误,导致组件无法正常渲染。

  4. useEffect 闭包与数据处理问题:useEffect依赖数组为空,但内部使用了user.Username,会导致闭包引用旧值;同时fetch返回的response未调用.json()就直接取response.data,无法正确获取接口数据。

解决方法

1. 统一子组件导入导出方式

检查每个子组件(FavoriteMovies、UserInfo、UpdateView、DeleteUser)的导出方式:

  • 如果子组件是默认导出(export default UserInfo),保持当前导入方式不变;
  • 如果子组件是命名导出(export const UserInfo = () => {}),修改导入语句为命名导入:
    import { UserInfo } from "./user-info";
    import { UpdateView } from "./update-user";
    // 其他子组件同理
    

2. 修复 toast 使用问题

如果需要函数式提示,改用react-toastify库:

  1. 安装依赖:npm install react-toastify
  2. 导入并配置:
    import { ToastContainer, toast } from 'react-toastify';
    import 'react-toastify/dist/ReactToastify.css';
    
    // 在组件返回的JSX末尾添加ToastContainer
    return (
      <Container className="profile-view">
        {/* 其他组件 */}
        <ToastContainer />
      </Container>
    )
    

3. 修正函数组件内方法定义

将removeFavMovie改为函数组件合法的定义方式:

const removeFavMovie = async (movies) => {
  const user = JSON.parse(localStorage.getItem("user")); // localStorage存的是字符串,需解析为对象
  console.log(user);
  const token = localStorage.getItem("token");
  console.log(token);
  fetch(`https://movies-couch-api.vercel.app/users/${user.Username}/movies/${movies._id}`,
  {
    method: "DELETE",
    headers: {Authorization: `Bearer ${token}`} // 修正拼写:header -> headers
  }) 
  .then((response) => {
      console.log(response);
      toast.success(`The Movie: ${movies._id} was removed from Favorite List`)
  })
  .catch(function (error) {
      console.error(" An error occurred" + error);
  })
}

4. 修复 useEffect 逻辑

useEffect(() => {
  const token = window.localStorage.getItem("token");
  fetch(`https://movies-couch-api.vercel.app/users/${user.Username}`,
  {
      method: "GET",
      headers: { Authorization: `Bearer ${token}` } 
  })
  .then((response) => {
      if (response.ok) {
          console.log("User data retrieved")
          return response.json(); // 解析response为JSON格式
      } else {
          console.log("User data could not be retrieved.")
          throw new Error('Failed to fetch user data');
      }
  })
  .then(data => {
      setMyUser(data); // 使用解析后的数据更新状态
      console.log(data);
  })
  .catch((error) => {
      console.error("An error occurred: " + error);
  });
}, [user.Username]); // 添加依赖,避免闭包导致的旧值问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 05:24:27