React - class 组件引用函数组件时出错
React - Error when class components reference function components
我有一个 react/django 应用程序。在我的 app.js 中,我正在测试从我的 API 中提取和呈现 JSON 的能力,但同时能够呈现 React 组件。我的 app.js 包含一个 App class 组件,该组件引用作为功能组件的 Navbar 和 Navitems。我还提到了我在图标文件夹中保存为 word.svg 的图标。我将在开发工具中包含错误消息,在图标文件夹中包含 arrow.svg 的代码,以及我的 App.js 文件夹。
错误:
Target container is not a DOM element.
React.createElement: 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.
Each child in a list should have a unique “key” prop
Element type is invlaid: react-dom.development.js expected a string or class/function but got: undefined
Check the render method of app
The above error occurred in the <a> componenet
App.js
import { render } from "react-dom";
import './index.css';
import { ReactComponent as BellIcon } from './icons/bell.svg';
import { ReactComponent as MessengerIcon } from './icons/messenger.svg';
import { ReactComponent as CaretIcon } from './icons/caret.svg';
import { ReactComponent as PlusIcon } from './icons/plus.svg';
import { ReactComponent as CogIcon } from './icons/cog.svg';
import { ReactComponent as ChevronIcon } from './icons/chevron.svg';
import { ReactComponent as ArrowIcon } from './icons/arrow.svg';
import { ReactComponent as BoltIcon } from './icons/bolt.svg';
import React, { useState, useEffect, useRef, Component } from 'react';
import { CSSTransition } from 'react-transition-group';
class App extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
loaded: false,
placeholder: "Loading"
};
}
componentDidMount() {
fetch("api/lead")
.then(response => {
if (response.status > 400) {
return this.setState(() => {
return { placeholder: "Something went wrong!" };
});
}
return response.json();
})
.then(data => {
this.setState(() => {
return {
data,
loaded: true
};
});
});
}
render() {
return (
<ul>
{this.state.data.map(contact => {
return (
<div>'
<Navbar>
<NavItem icon={<PlusIcon />} />
<NavItem icon={<BellIcon />} />
<NavItem icon={<MessengerIcon />} />
<NavItem icon={<CaretIcon />}>
<DropdownMenu></DropdownMenu>
</NavItem>
</Navbar>
<li key={contact.id}>
{contact.name} - {contact.email}
<h1>Hi</h1>
</li>
</div>
);
})}
</ul>
);
}
}
function Navbar(props) {
return (
<nav className="navbar">
<ul className="navbar-nav">{props.children}</ul>
</nav>
);
}
function NavItem(props) {
const [open, setOpen] = useState(false);
return (
<li className="nav-item">
<a href="#" className="icon-button" onClick={() => setOpen(!open)}>
{props.icon}
</a>
{open && props.children}
</li>
);
}
function DropdownMenu() {
const [activeMenu, setActiveMenu] = useState('main');
const [menuHeight, setMenuHeight] = useState(null);
const dropdownRef = useRef(null);
useEffect(() => {
setMenuHeight(dropdownRef.current?.firstChild.offsetHeight)
}, [])
function calcHeight(el) {
const height = el.offsetHeight;
setMenuHeight(height);
}
function DropdownItem(props) {
return (
<a href="#" className="menu-item" onClick={() => props.goToMenu && setActiveMenu(props.goToMenu)}>
<span className="icon-button">{props.leftIcon}</span>
{props.children}
<span className="icon-right">{props.rightIcon}</span>
</a>
);
}
return (
<div className="dropdown" style={{ height: menuHeight }} ref={dropdownRef}>
<CSSTransition
in={activeMenu === 'main'}
timeout={500}
classNames="menu-primary"
unmountOnExit
onEnter={calcHeight}>
<div className="menu">
<DropdownItem>My Profile</DropdownItem>
<DropdownItem
leftIcon={<CogIcon />}
rightIcon={<ChevronIcon />}
goToMenu="settings">
Settings
</DropdownItem>
<DropdownItem
leftIcon=""
rightIcon={<ChevronIcon />}
goToMenu="animals">
Animals
</DropdownItem>
</div>
</CSSTransition>
<CSSTransition
in={activeMenu === 'settings'}
timeout={500}
classNames="menu-secondary"
unmountOnExit
onEnter={calcHeight}>
<div className="menu">
<DropdownItem goToMenu="main" leftIcon={<ArrowIcon />}>
<h2>My Tutorial</h2>
</DropdownItem>
<DropdownItem leftIcon={<BoltIcon />}>HTML</DropdownItem>
<DropdownItem leftIcon={<BoltIcon />}>CSS</DropdownItem>
<DropdownItem leftIcon={<BoltIcon />}>JavaScript</DropdownItem>
<DropdownItem leftIcon={<BoltIcon />}>Awesome!</DropdownItem>
</div>
</CSSTransition>
<CSSTransition
in={activeMenu === 'animals'}
timeout={500}
classNames="menu-secondary"
unmountOnExit
onEnter={calcHeight}>
<div className="menu">
<DropdownItem goToMenu="main" leftIcon={<ArrowIcon />}>
<h2>Animals</h2>
</DropdownItem>
<DropdownItem leftIcon="">Kangaroo</DropdownItem>
<DropdownItem leftIcon="">Frog</DropdownItem>
<DropdownItem leftIcon="">Horse?</DropdownItem>
<DropdownItem leftIcon="">Hedgehog</DropdownItem>
</div>
</CSSTransition>
</div>
);
}
export default App;
const container = document.getElementById("app");
render(<App />, container);
arrow.svg
<svg viewBox="0 0 448 512">
<path fill="currentColor" d="M257.5 445.1l-22.2 22.2c-9.4 9.4-24.6 9.4-33.9 0L7 273c-9.4-9.4-9.4-24.6 0-33.9L201.4 44.7c9.4-9.4 24.6-9.4 33.9 0l22.2 22.2c9.5 9.5 9.3 25-.4 34.3L136.6 216H424c13.3 0 24 10.7 24 24v32c0 13.3-10.7 24-24 24H136.6l120.5 114.8c9.8 9.3 10 24.8.4 34.3z" class=""/>
</svg>
为封闭的 div 指定 key 属性。键入 li 元素是多余的:
{this.state.data.map((contact, index) => {
return (
<div key={contact.id}>'
<Navbar>
<NavItem icon={<PlusIcon />} />
<NavItem icon={<BellIcon />} />
<NavItem icon={<MessengerIcon />} />
<NavItem icon={<CaretIcon />}>
<DropdownMenu></DropdownMenu>
</NavItem>
</Navbar>
<li>
{contact.name} - {contact.email}
<h1>Hi</h1>
</li>
</div>
);
})}
我有一个 react/django 应用程序。在我的 app.js 中,我正在测试从我的 API 中提取和呈现 JSON 的能力,但同时能够呈现 React 组件。我的 app.js 包含一个 App class 组件,该组件引用作为功能组件的 Navbar 和 Navitems。我还提到了我在图标文件夹中保存为 word.svg 的图标。我将在开发工具中包含错误消息,在图标文件夹中包含 arrow.svg 的代码,以及我的 App.js 文件夹。
错误:
Target container is not a DOM element.
React.createElement: 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.
Each child in a list should have a unique “key” prop
Element type is invlaid: react-dom.development.js expected a string or class/function but got: undefined
Check the render method of app
The above error occurred in the <a> componenet
App.js
import { render } from "react-dom";
import './index.css';
import { ReactComponent as BellIcon } from './icons/bell.svg';
import { ReactComponent as MessengerIcon } from './icons/messenger.svg';
import { ReactComponent as CaretIcon } from './icons/caret.svg';
import { ReactComponent as PlusIcon } from './icons/plus.svg';
import { ReactComponent as CogIcon } from './icons/cog.svg';
import { ReactComponent as ChevronIcon } from './icons/chevron.svg';
import { ReactComponent as ArrowIcon } from './icons/arrow.svg';
import { ReactComponent as BoltIcon } from './icons/bolt.svg';
import React, { useState, useEffect, useRef, Component } from 'react';
import { CSSTransition } from 'react-transition-group';
class App extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
loaded: false,
placeholder: "Loading"
};
}
componentDidMount() {
fetch("api/lead")
.then(response => {
if (response.status > 400) {
return this.setState(() => {
return { placeholder: "Something went wrong!" };
});
}
return response.json();
})
.then(data => {
this.setState(() => {
return {
data,
loaded: true
};
});
});
}
render() {
return (
<ul>
{this.state.data.map(contact => {
return (
<div>'
<Navbar>
<NavItem icon={<PlusIcon />} />
<NavItem icon={<BellIcon />} />
<NavItem icon={<MessengerIcon />} />
<NavItem icon={<CaretIcon />}>
<DropdownMenu></DropdownMenu>
</NavItem>
</Navbar>
<li key={contact.id}>
{contact.name} - {contact.email}
<h1>Hi</h1>
</li>
</div>
);
})}
</ul>
);
}
}
function Navbar(props) {
return (
<nav className="navbar">
<ul className="navbar-nav">{props.children}</ul>
</nav>
);
}
function NavItem(props) {
const [open, setOpen] = useState(false);
return (
<li className="nav-item">
<a href="#" className="icon-button" onClick={() => setOpen(!open)}>
{props.icon}
</a>
{open && props.children}
</li>
);
}
function DropdownMenu() {
const [activeMenu, setActiveMenu] = useState('main');
const [menuHeight, setMenuHeight] = useState(null);
const dropdownRef = useRef(null);
useEffect(() => {
setMenuHeight(dropdownRef.current?.firstChild.offsetHeight)
}, [])
function calcHeight(el) {
const height = el.offsetHeight;
setMenuHeight(height);
}
function DropdownItem(props) {
return (
<a href="#" className="menu-item" onClick={() => props.goToMenu && setActiveMenu(props.goToMenu)}>
<span className="icon-button">{props.leftIcon}</span>
{props.children}
<span className="icon-right">{props.rightIcon}</span>
</a>
);
}
return (
<div className="dropdown" style={{ height: menuHeight }} ref={dropdownRef}>
<CSSTransition
in={activeMenu === 'main'}
timeout={500}
classNames="menu-primary"
unmountOnExit
onEnter={calcHeight}>
<div className="menu">
<DropdownItem>My Profile</DropdownItem>
<DropdownItem
leftIcon={<CogIcon />}
rightIcon={<ChevronIcon />}
goToMenu="settings">
Settings
</DropdownItem>
<DropdownItem
leftIcon=""
rightIcon={<ChevronIcon />}
goToMenu="animals">
Animals
</DropdownItem>
</div>
</CSSTransition>
<CSSTransition
in={activeMenu === 'settings'}
timeout={500}
classNames="menu-secondary"
unmountOnExit
onEnter={calcHeight}>
<div className="menu">
<DropdownItem goToMenu="main" leftIcon={<ArrowIcon />}>
<h2>My Tutorial</h2>
</DropdownItem>
<DropdownItem leftIcon={<BoltIcon />}>HTML</DropdownItem>
<DropdownItem leftIcon={<BoltIcon />}>CSS</DropdownItem>
<DropdownItem leftIcon={<BoltIcon />}>JavaScript</DropdownItem>
<DropdownItem leftIcon={<BoltIcon />}>Awesome!</DropdownItem>
</div>
</CSSTransition>
<CSSTransition
in={activeMenu === 'animals'}
timeout={500}
classNames="menu-secondary"
unmountOnExit
onEnter={calcHeight}>
<div className="menu">
<DropdownItem goToMenu="main" leftIcon={<ArrowIcon />}>
<h2>Animals</h2>
</DropdownItem>
<DropdownItem leftIcon="">Kangaroo</DropdownItem>
<DropdownItem leftIcon="">Frog</DropdownItem>
<DropdownItem leftIcon="">Horse?</DropdownItem>
<DropdownItem leftIcon="">Hedgehog</DropdownItem>
</div>
</CSSTransition>
</div>
);
}
export default App;
const container = document.getElementById("app");
render(<App />, container);
arrow.svg
<svg viewBox="0 0 448 512">
<path fill="currentColor" d="M257.5 445.1l-22.2 22.2c-9.4 9.4-24.6 9.4-33.9 0L7 273c-9.4-9.4-9.4-24.6 0-33.9L201.4 44.7c9.4-9.4 24.6-9.4 33.9 0l22.2 22.2c9.5 9.5 9.3 25-.4 34.3L136.6 216H424c13.3 0 24 10.7 24 24v32c0 13.3-10.7 24-24 24H136.6l120.5 114.8c9.8 9.3 10 24.8.4 34.3z" class=""/>
</svg>
为封闭的 div 指定 key 属性。键入 li 元素是多余的:
{this.state.data.map((contact, index) => {
return (
<div key={contact.id}>'
<Navbar>
<NavItem icon={<PlusIcon />} />
<NavItem icon={<BellIcon />} />
<NavItem icon={<MessengerIcon />} />
<NavItem icon={<CaretIcon />}>
<DropdownMenu></DropdownMenu>
</NavItem>
</Navbar>
<li>
{contact.name} - {contact.email}
<h1>Hi</h1>
</li>
</div>
);
})}