[英]React - Error when class components reference function components
I have a react/django app.我有一个 react/django 应用程序。 In my app.js, I am testing out the ability to pull & render JSONs from my API, but at the same time be able to render react components.在我的 app.js 中,我正在测试从我的 API 中提取和呈现 JSON 的能力,但同时能够呈现反应组件。 My app.js consists of an App class component that refers to Navbar and Navitems that are function components.我的 app.js 由一个 App class 组件组成,该组件指的是作为 function 组件的 Navbar 和 Navitems。 I also refer to icons that I have saved as word.svg in an icons folder.我还引用了图标文件夹中保存为 word.svg 的图标。 I am going to include the error messages in dev tools, code for arrow.svg in icon folder, and my App.js folder.我将在开发工具中包含错误消息、arrow.svg 的代码在图标文件夹和我的 App.js 文件夹中。
Error:错误:
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应用程序.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
<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>
Specify key attribute for the enclosing div .为封闭的div指定key属性。 Key in li element is redundant: 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>
);
})}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.