Reputation: 669
Im trying to create an array to store my category links and then display them however I'm getting nothing displaying in my DOM. Any help would be appreciated :)
import React from "react";
import { SidebarCategory } from './SidebarCategory';
class SidebarCategories extends React.Component {
constructor() {
super();
this.state = {
categories: []
}
}
componentWillMount() {
this.setState({categories: [
{
id: 1,
icon: "icon",
title: "Home",
},
{
id: 2,
icon: "icon",
title: "Gallery",
}
]});
}
render() {
return (
<ul className="sidebar__categories container-fluid">
{this.state.categories.map(category => {
return (
<SidebarCategory key={category.id} title={category.title} />
)
})};
</ul>
);
}
}
export default SidebarCategories;
edit:
console error:
bundle.js:357 Warning: 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. Check the render method of Sidebar
.
in Sidebar (created by App)
in div (created by App)
in App
sidebarCategory.js
import React from "react";
export class SidebarCategory extends React.Component {
render() {
const SidebarCategory = ({ title }) => {
return (<div className="sidebarCategory">{title}</div>);
}
}
}
sidebar.js:
import React from "react";
import { SidebarCategories } from "./SidebarCategories";
export class Sidebar extends React.Component {
render() {
return (
<div className="sidebar col-sm-2">
<div className="row">
<div className="sidebar__header col">
<img alt="Logo" className="img-fluid sidebar__header__logo" src="../resources/img/logo-white.png" />
{'\u00A0'} <h4 className="i-block">Title</h4>
</div>
</div>
<div className="row">
<div className="sidebar__user container-fluid">
<div className="row">
<div className="col-sm-4">
<img alt="User DP" className="sidebar__user__img img-fluid rounded-circle" src="http://via.placeholder.com/100x100" />
</div>
<div className="col-sm-8">
<p><strong>Welcome</strong><br />
Mark Hughes</p>
</div>
</div>
</div>
</div>
<div className="row">
<SidebarCategories />
</div>
</div>
);
}
}
index.js:
import React from "react";
import { render } from "react-dom";
import Sidebar from "./components/sidebar";
import Content from "./components/content";
class App extends React.Component {
render() {
return (
<div className="row">
<Sidebar />
<Content />
</div>
);
}
}
render(<App className="container-fluid"/>, window.document.getElementById("app"));
Upvotes: 0
Views: 35492
Reputation: 109
I believe the issue is in your sidebarCategory.js, you created a stateless (arrow function) component inside a stateful component.
since its just a component that render data from its props you can use the stateless/arrow function alone like this.
const SidebarCategory = ({ title }) => {
return (<div className="sidebarCategory">{title}</div>);
}
export default SidebarCategory; // this way its exported as default component, import it without using curly brackets (import SidebarCategory from './SidebarCategory';
// OR
export SidebarCategory; // this way its exported as non-default component, import it using the curly brackets (import {SidebarCategory} from './SidebarCategory';
Upvotes: 0
Reputation: 2133
Try these: index.js
import React from "react";
import { render } from "react-dom";
import Sidebar from "./components/sidebar";
import Content from "./components/content";
class App extends React.Component {
render() {
return (
<div className="row">
<Sidebar />
<Content />
</div>
);
}
}
render(<App className="container-fluid"/>, document.getElementById("app"));
Sidebar.js
import React from "react";
import SidebarCategories from "./SidebarCategories";
class Sidebar extends React.Component {
render() {
return (
<div className="sidebar col-sm-2">
<div className="row">
<div className="sidebar__header col">
<img alt="Logo" className="img-fluid sidebar__header__logo" src="../resources/img/logo-white.png" />
{'\u00A0'} <h4 className="i-block">Title</h4>
</div>
</div>
<div className="row">
<div className="sidebar__user container-fluid">
<div className="row">
<div className="col-sm-4">
<img alt="User DP" className="sidebar__user__img img-fluid rounded-circle" src="http://via.placeholder.com/100x100" />
</div>
<div className="col-sm-8">
<p><strong>Welcome</strong><br />
Mark Hughes</p>
</div>
</div>
</div>
</div>
<div className="row">
<SidebarCategories />
</div>
</div>
);
}
}
export default Sidebar;
SidebarCategory.js
import React from "react";
class SidebarCategory extends React.Component {
render() {
return (
<div className="row">
<div className="col-sm-10">
{this.props.category.title}
</div>
</div>
);
}
}
export default SidebarCategory;
SidebarCategories.js
import React from "react";
import SidebarCategory from './SidebarCategory';
class SidebarCategories extends React.Component {
constructor() {
super();
this.state = {
categories: []
}
}
componentWillMount() {
this.setState({categories: [
{
id: 1,
title: "Home",
},
{
id: 2,
title: "Gallery",
}
]});
}
render() {
let list = this.state.categories.map((category) => {
<li className="sidebar__category container-fluid" key={category.id}><SidebarCategory category={category} /></li>
});
return (
<ul className="sidebar__categories container-fluid">
{list}
</ul>
);
}
}
export default SidebarCategories;
Upvotes: 0
Reputation: 7764
First in SidebarCategories
import {SidebarCategory}... //with curly braces
Second in Sidebar:
import SidebarCategories from "./SidebarCategories"; //without curly braces
See:
export class SidebarCategory //no default -> import {SidebarCategory} from...
export default SidebarCategories; //with default -> import SidebarCategories from ...
Upvotes: 1
Reputation: 738
import React from "react";
import SidebarCategory from './SidebarCategory';
class SidebarCategories extends React.Component {
constructor() {
super();
this.state = {
categories: []
}
}
componentWillMount() {
this.setState({categories: [
{
id: 1,
title: "Home",
},
{
id: 2,
title: "Gallery",
}
]});
}
render() {
return (
<ul className="sidebar__categories container-fluid">
<SidebarCategory categories={this.state.categories} />
</ul>
);
}
}
export default SidebarCategories;
And add this in your SidebarCategory file:-
import React from "react";
export class SidebarCategory extends React.Component {
render() {
return (
<li className="sidebar__category container-fluid">
<div className="row">
<div className="col-sm-10">
{this.props.categories.map((category, key) =>(
<span key={key}>{category.title}</span>
))}
</div>
</div>
</li>
);
}
}
Upvotes: 3
Reputation: 63524
At the moment you're not iterating over your categories you have held in state, so the first thing is to map
over them and provide your sub-component <SidebarCategory>
the data it needs; a key from the category id, and the title.
render() {
return (
<ul className = "sidebar__categories container-fluid">
{this.state.categories.map(category => {
return (
<SidebarCategory
key={category.title}
title={category.title}
/>
)
})}
</ul>
);
}
Then your <SidebarCategory>
component should return a div
(for example) the title of which is filled in from the props
that you've provided it.
const SidebarCategory = ({ title }) => {
return <div className="SidebarCategory">{title}</div>
}
export default SidebarCategory;
Upvotes: 1