Create a list from Array React JS - javascript

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"));

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>
);
}
}

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;

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 ...

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;

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';

Related

React Pass const from file to another

I have two page with same logic but different content and i want to use the same object but parse different json content.
Projects and Experience page use the same ProjectList and Project. I want to pass different content to Projects.js and Experience.js
Project:
import React, {Component} from 'react';
import Navigation from "../components/Nagivation";
import ProjectList from "../components/experience/ProjectList";
import { portfolioData } from '../data/portfolioData';
export default class Projects extends Component {
state = {
projects:portfolioData
};
render() {
let {projects} = this.state;
return (
<div className="portfolio">
<Navigation/>
{
<ProjectList
item={projects}
/>
}
</div>
);
}
};
ProjectList
import React, {Component} from 'react';
import Project from "./Project";
export default class ProjectList extends Component {
render() {
console.log(this.props.item)
let {projects} = this.props.item;
return (
<div className="portfolioContent">
<h3 className="radioDisplay">Test</h3>
<div className="projects">
{
projects.map(item => {
return (
<Project
key={item.id}
item={item}
/>
)
})
}
</div>
</div>
);
}
}
I have Uncaught TypeError: Cannot read properties of undefined (reading 'map') on the line <div className="projects">
Project.js
import React, {Component} from 'react';
export default class Project extends Component {
state = {
showInfo: false
}
handleInfo = () => {
this.setState({
showInfo:!this.state.showInfo
})
}
render() {
let {name, periode, info, picture} = this.props.item
return (
<div className="project">
<h5>{periode}</h5>
<h3>{name}</h3>
<img src={picture} alt="" onClick={this.handleInfo} />
//some stuffs
);
}
}
I don't want to use map, because i want to iterate only in ProjectList.

When I edit line 14 addReminder function the app break any insight to what I am doing wrong?

In this code below, I keep running into this error message "Error: Actions may not have an undefined "type" property. Have you misspelled a constant?" This I received the error message after editing my addReminder on line 14. Any insight?
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { addReminder } from '../action';
class App extends Component{
constructor(props) {
super(props);
this.state = {
text: ''
}
}
addReminder() {
this.props.addReminder(this.state.text);
}
render(){
return (
<div className="App">
<div className="title">
Reminder Pro
</div>
<div className="form">
<div className="form=group">
<input
className="form-control"
placeholder="I have to..."
onChange={event => this.setState({text: event.target.value})}
/>
</div>
<button
type="button"
className="btn btn-success"
onClick={() => this.addReminder()}
>
Add Reminder
</button>
</div>
</div>
)
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({addReminder}, dispatch);
}
export default connect(null, mapDispatchToProps)(App);

onClick inside mapped object JSX for React NextJS not working

I have a component :
import React, { Component } from 'react';
import ImageItem from '../components/ImageItem';
class ImageList extends Component {
handleClick() {
console.log('Testing testing...'); // ---> This is not working.
}
render() {
const images = this.props.images.map(image => {
return (
<ImageItem
onClick={this.handleClick}
key={image.id}
image={image.src}
title={image.title}
/>
);
});
return (
<div className="image-list" ref={el => (this.el = el)}>
{images}
</div>
);
}
}
export default ImageList;
However, my onClick is not console logging anything out when it is inside the mapped function.
This is my ImageItem component:
import React, { Component } from 'react';
class ImageItem extends Component {
render() {
return (
<a href="#">
<img
className="portfolio-image"
src={this.props.image}
alt={this.props.title}
/>
</a>
);
}
}
export default ImageItem;
What am I doing wrong here?
You are not assigning the click handler to your component it should look like this :
class ImageItem extends Component {
render() {
return (
<a href="#" onClick={this.props.onClick}>
<img
className="portfolio-image"
src={this.props.image}
alt={this.props.title}
/>
</a>
);
}
}
export default ImageItem;

Get the component of a rendered element

Currently, I'm making a modal system with React.
So I have a button in a sidebar and my modal is a div in the body.
I have two component that are rendered in the render function of the main component of my app:
MyModal
MyModalOpenButton
Here is what I need:
When the event onClick of the MyModalOpenButton is triggered, I need to execute a function stored in the MyModal component.
So I basically need to store the ref of MyModal in a var.
How can I do this ?
Codes:
import * as ReactDOM from "react-dom";
import * as React from "react";
import { MyModal } from "./component/modal/my-modal";
import { SettingsButtons } from "./component/settings-buttons";
import { CustomComponent } from "./custom-component";
class App extends CustomComponent<{}, {}>{
constructor() {
super();
}
render() {
return (
<div>
<div className="sidebar">
<ul>
<li>
1
</li>
<li>
2
</li>
<li>
3
</li>
</ul>
<SettingsButtons />
</div>
<div className="mainContent">
</div>
<footer>TODO</footer>
<MyModal />
</div>
);
}
}
const app: App = ReactDOM.render(<App />, document.querySelector("#root")) as App;
And
import * as ReactDOM from "react-dom";
import * as React from "react";
import { CustomComponent } from "./../../custom-component";
import { ButtonComponent } from "./button";
export class MyModalOpenButton extends ButtonComponent<{}, {}> {
constructor() {
super();
}
render() {
return (
<li id="open-button" onClick={this.onClick}>
<i className="fa fa-plus" aria-hidden="true"></i>
</li>
);
}
onClick(event: React.MouseEvent<HTMLElement>) {
// Should open the modal
}
}
You haven't shared your code, so I can't give you an answer that will match your case specifically, but in general:
class MyModal extends React.Component<any, any> {
public render() {
...
}
public onButtonClick() {
...
}
}
interface MyModalOpenButtonProps {
onClick: () => void;
}
class MyModalOpenButton extends React.Component<MyModalOpenButtonProps, any> {
public render() {
return <button onClick={ this.props.onClick } />
}
}
class Main extends React.Component<any, any> {
private myModal: MyModal;
public render() {
return (
<div>
<MyModalOpenButton onClick={ this.onButtonClick.bind(this) } />
<MyModal ref={ modal => this.myModal = modal } />
</div>
);
}
private onButtonClick() {
this.myModal.onButtonClick();
}
}

Calling a function from a different react file

I'm close to getting this to work. Hoping someone can help me with this.
I have 2 React files. One being the Container and the other being the Nav component.
Inside my container component which is called _template.js, I'm importing a modal npm package. I created a showModal function inside this container file that I'm trying to access inside the Nav component.
This is what I have so far and receive this error Uncaught TypeError: Cannot read property 'modal' of undefined
_template.js:
import React from 'react';
import { Link } from 'react-router';
import { prefixLink } from 'gatsby-helpers';
import { config } from 'config';
import Headroom from 'react-headroom';
import Nav from './nav.js';
import '../css/main.scss';
import Modal from 'boron/DropModal';
const modalStyle = {
minHeight: '500px',
backgroundColor: '#303841'
};
const backdropStyle = {
backgroundColor: '#F6C90E'
};
const contentStyle = {
backgroundColor: '#303841',
padding: '3rem'
};
export default class RootTemplate extends React.Component {
static propTypes = {
location: React.PropTypes.object.isRequired,
children: React.PropTypes.object.isRequired,
}
static contextTypes = {
router: React.PropTypes.object.isRequired,
}
constructor() {
super();
}
showModal () {
this.refs.modal.show();
}
render() {
return (
<div>
<Headroom>
<Nav showModal={this.showModal}/>
</Headroom>
<Modal ref="modal" modalStyle={modalStyle} contentStyle={contentStyle} backdropStyle={backdropStyle}>
<form>
<label>Name:</label>
<input type="text"/>
<label>Email:</label>
<input type="email"/>
<label>Message:</label>
<input type="text-area"/>
<input type="submit" placeholder="Submit" />
</form>
</Modal>
{this.props.children}
</div>
);
}
}
And my Nav.js file:
import React from 'react';
import { Link } from 'react-router';
import { prefixLink } from 'gatsby-helpers';
import { Nav, NavGroup, NavItem, NavToggle, Icon } from 're-bulma';
export default class nav extends React.Component {
static propTypes = {
name: React.PropTypes.string,
};
constructor(props) {
super(props);
}
render() {
return (
<div>
<Nav>
<NavGroup align="left">
<NavItem>
<Link to={prefixLink('/')}>
<h2>Dillon Raphael</h2>
</Link>
</NavItem>
</NavGroup>
<NavToggle />
<NavGroup align="right" isMenu>
<NavItem>
</NavItem>
<NavItem>
</NavItem>
<NavItem>
<a href="#" onClick={::this.props.showModal}>Let's Work!</a>
</NavItem>
</NavGroup>
</Nav>
</div>
);
}
}
Notice the <a href="#" onClick={::this.props.showModal}>Let's Work!</a> this is where I'm trying to call the showModal function that I pass down from the _template.js file.
Add to your constructor, in _template.js file this code:
this.showModal = this.showModal.bind(this);
The constructor then should look like this:
constructor(props) {
super(props);
this.showModal = this.showModal.bind(this);
}

Categories

Resources