React - Map content inside a div - reactjs

Good Morning! Why does my map content stay outside the "blog--div" div?
It's getting loose on Body and I do not know why. Help-me, please!
I try to put a border around the contents of the "blog--div" but the content becomes loose, making it impossible to apply styles.
imports[...]
class Blog extends Component {
constructor(props) {
super(props)
this.state = {
post: [],
}
}
componentDidMount() {
this.setState({ isLoading: true })
fetch(`${API}`)
.then(res => res.json())
.then(res => {
this.setState({
post: [res],
isLoading: false,
})
})
}
render() {
const { isLoading } = this.state
if (isLoading) {
return <Loading />
}
return (
<div className="blog">
<p className="blog__title">Blog</p>
{this.renderBlog()}
</div>
)
}
renderBlog() {
const page = this.state.post.map((post, key) => {
return (
<div className="blog--div" key={key}>
<div className="blog__post">
<div className="blog__post--title">
<p><a target="_blank" rel="noopener noreferrer" href={post[0].link}>{post[0].title.rendered.replace('Visit.Rio', 'Projeto 1')}</a></p>
</div>
<div className="blog__post--description">
<p>{post[0].excerpt.rendered.replace('Visit.Rio', 'Projeto 1')}</p>
</div>
</div>
</div>
)
})
return page
}
}
export default Blog

Related

Conditional rendering element from a list as a modal in React

I am very new to programming and working on an MVP project for a FS app where I have a small database of books which I render through a .map. Currently, I am rendering the cover of all the books in my database and when I click on the cover it shows the title, author and summary. The functionality is working but it is looking rubbish as when I click any book it pushes everything around and I would like for it to show as a modal box above my list of books. This is my code below, do you have any idea how to achieve that? Thanks so much :)
import Filter from "./components/filter"
import './App.css';
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
books:[],
showBook: []
};
}
componentDidMount() {
this.getBookclub();
}
getBookclub = () => {
fetch(`/books`)
.then(response => response.json())
.then(response => {
this.setState({ books: response });
});
};
handleClick(e){
for (let i = 0 ; i < this.state.books.length ; i++) {
this.state.showBook[i] = false;
}
let bookShow = [...this.state.showBook];
bookShow[e.target.name-1] = true;
this.setState({
showBook: bookShow
});
}
renderLibrary() {
return this.state.books.map((books,id) => {
return(
<li key={id} className="book-list">
<span onClick ={() => this.getBookclub(books.id)}>
<div>
**<img onClick={(e) => this.handleClick(e)} name={books.id} src={books.cover} alt={books.title}/>
</div>
<div className={this.state.showBook[books.id-1] ? "bookDetails" : "bookhidden"}>
<br/>
<div className="cover-book-show">
<h5>{books.title}</h5>
</div>
<div className="author-book-show">
<h6>{books.author}</h6>
</div>
<div className="summary-book-show">
<p>{books.summary}</p>
</div>**
</div>
</span>
</li>
)
})}
filterBook(filteredList){
this.setState({
books: filteredList
})
}
render() {
return (
<div>
<h1>Books</h1>
<div>
<Filter filterBook={filteredList => this.filterBook(filteredList)}/>
</div>
<br/>
<ul>
**<div className="all-books">
{this.renderLibrary()}
</div>**
</ul>
</div>
);
}
}```

How to reset father component onclick react

I'm doing a menu with a submenu with React. Clicking on the main menu (Example: CRM) creates the submenu (Example Hijo: Argumentarios) but when clicking on the following menu item (Example Padre: Permisos) "Argumentarios" is not deleted and the submenu of "Permisos" is also created.
I need that when pressing in the menu it shows its submenu and eliminates those of the other siblings.
This is a part of my json file
[
{
"Id":"114",
"Padre":"CRM",
"Hijo":"Argumentarios"
},
{
"Id":"115",
"Padre":"CRM",
"Hijo":"Argumentarios"
},
{
"Id":"116",
"Padre":"CRM",
"Hijo":"Argumentarios"
},
{
"Id":"44",
"Padre":"Permisos",
"Hijo":"root"
},
{
"Id":"45",
"Padre":"Permisos",
"Hijo":"root"
},
{
"Id":"47",
"Padre":"Permisos",
"Hijo":"root"
},
{
"Id":"50",
"Padre":"Telefonia",
"Hijo":"Audio"
},
{
"Id":"51",
"Padre":"Telefonia",
"Hijo":"Audio"
}
]
For confidential reasons I can not show the actual file.
In my next code I change the fetch for a fake json url
import React, { Component } from 'react';
import Icon from './Icon';
class Nav extends Component{
constructor(props){
super(props)
this.state = {
menuSubmenu:[],
}
}
componentWillMount(){
fetch('fake/json_menu.php')
.then(response => response.json())
.then(menuSubmenu =>{
menuSubmenu.forEach(datos => {
let data = {
menu:datos.Padre,
submenu:datos.Hijo,
id:datos.Id,
descripcion:datos.Description,
url:datos.URL
}
this.setState({
menuSubmenu:this.state.menuSubmenu.concat([data])
})
})
})
}
render() {
if (this.state.menuSubmenu.length > 0) {
return(
<nav className="nav">
<div className="menu">
<ul className="list">
{this.state.menuSubmenu.map(datos => <Menu key={datos.id} menu={datos.menu} submenu={datos.submenu} descripcion={datos.descripcion} url={datos.url}/>)}
</ul>
<div className="content-bnt">
<button id="desplegar" className='btn btn--rounded'>
<Icon icon="flecha" className='ico-flecha'/>
</button>
</div>
</div>
</nav>
);
}
return (<p>Cargando usuarios...</p>);
}
}
class Menu extends Component{
constructor(props){
super(props)
this.state = {
abrirSubmenu: false,
}
this.submenuClick = this.submenuClick.bind(this);
}
submenuClick() {
this.setState(state => ({
abrirSubmenu: !state.abrirSubmenu
}));
//alert('Click!')
}
render(){
return (
<>
<li className="list__item">
<button title={this.props.menu} id={"mn-" + this.props.menu} className="desplegable" onClick={this.submenuClick.bind(this)}><Icon icon="auriculares" className='ico-auriculares'/>{this.props.menu}</button>
{
this.state.abrirSubmenu
? (
<div id="sb-crm" className="submenu">
<h3 className="nav--title"><Icon icon="descargar" className='ico-descargar'/>{this.props.submenu}</h3>
<ul className="list">
<li className="list__item">
<a href={this.props.url} title={this.props.descripcion}>{this.props.descripcion}</a>
</li>
</ul>
</div>
)
: (
null
)
}
</li>
</>
)
}
}
export default Nav;
I hope to show only one of the menu items at the same time.
¡Thanks a lot!

how to make api call using props

im trying to make an api call in one component using state from a different component , however when i use props in the API call im getting an error saying cannot read property props of undefined. basicly im trying to make an api call using data from a different component in then display it in the main component , but am not sure how to do it. Can someone pls tell me what im doing wrong ? thanks for the help!
class App extends Component {
constructor() {
super();
this.state = {
places2: [] ,
isLoaded2: true,
isLoaded: true,
latitude: 37.774929,
longitude: -122.419416,
};
// this is the data i want to pass
geocodeByAddress(address)
.then(res => getLatLng(res[0]))
.then(({ lat, lng }) => {
this.setState({
latitude: lat,
longitude: lng,
});
})
.catch(error => {
this.setState({ isGeocoding: false });
console.log('error', error); // eslint-disable-line no-console
});
}
render() {
return (
<div id="h">
{this.state.isLoaded ?
<Health
latitude={this.state.latitude}
longitude={this.state.longitude}
parentMethod={this.parentMethod}
parentMethod2={this.parentMethod2}
/>
: <div>.</div>}
<Map center= {{lat: this.state.latitude, lng: this.state.longitude}}/>
{this.state.isLoaded ?
<div id="location-basic-info" >
<UserForm
address={this.state.address}
Latitude={this.state.latitude}
Longitude={this.state.longitude}
/>
</div> : <div>.</div>}
{this.state.isLoaded2 ?
<Health
latitude={this.state.latitude}
longitude={this.state.longitude}
parentMethod={this.parentMethod}
parentMethod2={this.parentMethod2}
/>
: <div>.</div>}
{this.state.isLoaded2 ?
<div id="location-basic-info" >
<div> {this.state.place} {this.state.places2} </div>
</div> : <div>.</div>}
</div>
<div>
</div>
</div>
);
}
};
export default App;
health.js
class Health extends Component {
constructor() {
super();
this.state = {
zoom: 13,
maptype: 'roadmap',
place_formatted: '',
place_id: '',
place_location: '',
address: '',
latitude: 37.774929,
longitude: -122.419416,
marker:[],
places: [], isLoaded: false,
places2: []
};
}
getplace(){
var param = {
//this is giving me the error
lat: this.props.latitude,
long: this.props.longitude,
temp:1
}
axios.post(`http://localhost:5000/search-champ`, {
param
}).then((data)=>{
this.setState({places: data});
console.log( this.state.places);
console.log(data);
const places = data.data.data[0].results.slice(0,10).map((place) => {
console.log(place.name)
console.log(place.geometry.location.lat)
console.log(place.geometry.location.lng)
let name = place.name;
let vicinity= place.vicinity;
return <div class="col-xs-6 col-sm-6">
<ul id="places-list">
<li><a onClick={() => this.hello(name, vicinity)}> {place.name} </a> </li>
</ul>
</div>
})
console.log('places', places);
const places2 = data.data.data[1].results.slice(0,10).map((place) => {
console.log(place.name)
console.log(place.geometry.location.lat)
console.log(place.geometry.location.lng)
let name = place.name;
let vicinity= place.vicinity;
return <div class="col-xs-6 col-sm-6">
<ul id="places-list">
<li><a onClick={() => this.hello(name, vicinity)}> {place.name} </a> </li>
</ul>
</div>
});
this.setState({ place: places , isLoaded: true});
this.setState({ places2: places2 , isLoaded: true});
})
}
render(){
return(
<div>
<ul class="nav nav-pills" id="f">
<li class="active" onClick={this.props.parentMethod}> Info</li>
<li onClick={this.props.parentMethod2}>Food</li>
<li onClick={this.getplace}>Health</li>
<li>Menu 3</li>
</ul>
{this.state.isLoaded2 ?
<div id="location-basic-info" >
<div> {this.state.places} {this.state.places2} </div>
</div> : <div>.</div>}
</div>
);
}};
export default Health;
Your call to the api must be in the componentDidMount method.
componentDidMount: This method is called once all our children Elements and our Component instances are mounted onto the Native UI
Simple life cycle:
class Example extends React.Component {
constructor()
{
console.log('constructor')
}
componentWillMount()
{
console.log('Pre-mounting ')
}
componentDidMount()
{
console.log('Post-mounting ')
//TODO: call api axios or fetch
}
render()
{
console.log('render ui')
return(....)
}
}
Also i saw something like that in your code:
render() {
// BAD: Do not do this!
this.setState({ place: places , isLoaded: true});
this.setState({ places2: places2 , isLoaded: true});
}
Happy coding!

React: change order list when button clicked

I am making my first app with Javascript and React and started with a page which views a shopping list. It gets the items from an api call.
If the user clicks on the button 'done' (or should I use an checkbox?) This product should go to the bottom of the list (and be grayed out with css but thats not the problem).
The problem is, I have no clue how to do this. Can anyone help me out a bit?
This is my code:
import React from 'react';
//import image from '../images/header.png';
//import Collapsible from './Collapsible';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
orders: []
}
}
componentWillMount() {
localStorage.getItem('orders') && this.setState({
orders: JSON.parse(localStorage.getItem('orders')),
isLoading: false
})
}
componentDidMount() {
if (!localStorage.getItem('orders')){
this.fetchData();
} else {
console.log('Using data from localstorage');
}
}
fetchData() {
fetch('http://localhost:54408/api/orders/all/15-03-2018')
.then(response => response.json())
.then(parsedJSON => parsedJSON.map(product => (
{
productname: `${product.ProductName}`,
image: `${product.Image}`,
quantity: `${product.Quantity}`,
isconfirmed: `${product.IsConfirmed}`,
orderid: `${product.OrderId}`
}
)))
.then(orders => this.setState({
orders,
isLoading: false
}))
.catch(error => console.log('parsing failed', error))
}
componentWillUpdate(nextProps, nextState) {
localStorage.setItem('orders', JSON.stringify(nextState.orders));
localStorage.setItem('ordersDate', Date.now());
}
render() {
const {isLoading, orders} = this.state;
return (
<div>
<header>
<img src="/images/header.jpg"/>
<h1>Boodschappenlijstje <button className="btn btn-sm btn-danger">Reload</button></h1>
</header>
<div className={`content ${isLoading ? 'is-loading' : ''}`}>
<div className="panel">
{
!isLoading && orders.length > 0 ? orders.map(order => {
const {productname, image, quantity, orderid} = order;
return<div className="product" key={orderid}>
<div className="plaatjediv">
<img className="plaatje" src={image} />
</div>
<div className="productInfo">
<p>{productname}</p>
<p>Aantal: {quantity}</p>
<p>ID: {orderid}</p>
</div>
<div className="bdone">
<button className="btn btn-sm btn-default btndone">Done</button>
</div>
</div>
}) : null
}
</div>
<div className="loader">
<div className="icon"></div>
</div>
</div>
</div>
);
}
}
export default App;
You can achieve by using this :
this.handleDoneAction = event = > {
let itemIndex = event.target.getAttribute("data-itemIndex");
let prevOrders = [...this.state.orders];
var itemToMoveAtLast = prevOrders.splice(itemIndex, 1);
var updatedOrderList = prevOrders.concat(itemToMoveAtLast);
this.setState({order: updatedOrderList})
}
I have attach an event handler on the button handleDoneAction.
<button className="btn btn-sm btn-default btndone" data-itemIndex={index} onClick={this.handleDoneAction}>Done</button>
the attribute data-itemIndex is the index of the object in orders array.
And your map function will be like this:
orders.map((order, index) => {
//content
})
ANd for the different style effects on the done products, I will suggest you to use different array for all done products.

Highlight item onClick - React.js

Add underscore to category-item onClick and remove underscore for any other item. Found some answers on how to do this with only two components, a "item-container-component" and "item-components". But i have three components involved. This is what I hope to achieve:
Archive-component (mother component):
class Archive extends React.Component {
constructor(props){
super(props);
this.state = {
products: [],
category: "",
activeIndex: 0
}
this.filterHandler = this.filterHandler.bind(this);
}
filterHandler(tag, index){
console.log('INDEX: ' + index);
this.setState({
category: tag,
activeIndex: index
})
}
componentDidMount(){
const myInit = {
method: "GET",
headers: {
"Content-Type": "application/json"
}
};
fetch("/getProducts", myInit)
.then((res) => {
return res.json();
})
.then((data) => {
this.setState({products:data});
})
.catch(function(err) {
console.log('ERROR!!! ' + err.message);
});
}
render() {
return (
<div>
<Menu />
<div className="archive-container">
<div className="archive-wrapper">
<CategoryContainer
filterHandler={this.filterHandler}
products={this.state.products}
activeIndex={this.state.activeIndex}
/>
<br/><br/>
<ProductContainer
products={this.state.category.length
? this.state.products.filter((prod) => prod.category === this.state.category)
: this.state.products.filter((prod) => prod.category === 'Paint')
}
/>
</div>
</div>
<Footer />
</div>
);
};
};
Category-container component:
class CategoryContainer extends Component {
render(){
const categories = [...new Set(this.props.products.map(cat => cat.category))];
return (
<div>
<ul className="filterList">{
categories.map((cat, index) =>
<CategoryItem
key={index}
index={index}
category={cat}
active={index === this.props.activeIndex}
handleClick={() => this.props.filterHandler(cat, index)}
/>
)
}</ul>
</div>
);
};
};
Category-item component:
class CategoryItem extends Component {
render(){
return (
<div>
<li
className={this.props.active ? 'active' : 'category'}
onClick={this.props.handleClick}
>
{this.props.category}
</li>
</div>
);
};
};
Yelp!
M
Suppose you have a li tag for which you want to change the color of.
you could probably try something like this.
<li id="colorChangeOnClick" class="redColor" onclick={this.onClickFunction()}></li>
Then in your react class you can have the on click function with parameters e:
onClick(e) {
//This would give you all the field of the target
console.log(e.target.elements);
// you can do all sorts of Css change by this way
e.target.element.class="newGreenColor";
}
Also make sure to make a state or a prop change otherwise the page would not render again.

Resources