I'm making a simple shopping cart app using Redux. Right now every time I change page, actions are automatically get called for three times which is equal to the number of items. If I go to Cart page, removeItems action gets called three times so there's no way I can add items to cart so far. It might be a problem about router, but I can't spot the problem. Could anyone explain me what is the problem?
Home.js
import React from 'react';
import { connect } from 'react-redux';
import { addToCart } from '../actions';
class Home extends React.Component {
handleClick = id => {
this.props.addToCart(id)
}
renderList = () => {
return this.props.cart.slice(0, 3).map(item => {
return (
<div className="card" key={item.id} style={{width: "200px", float: "left", marginRight: "20px"}}>
<div className="card-image">
<img src={item.imageUrl} alt={item.name} />
<span className="card-title">{item.name}</span>
<span to="/"
className="btn-floating halfway-fab waves-effect waves-light red"
onClick={this.handleClick(item.id)}
>
<i className="material-icons">add</i>
</span>
</div>
<div className="card-content">
<p>{item.desc}</p>
<p><b>${item.price}</b></p>
</div>
</div>
)
})
}
render() {
console.log(this.props.cart)
return (
<div className="container">
<h3>Home</h3>
<div className="box">
{this.renderList()}
</div>
</div>
)
}
}
const mapStateToProps = state => {
return { cart: state.cart.items }
}
const mapStateToDispatch = dispatch => {
return {
addToCart: (id) => { dispatch(addToCart(id)) }
}
}
export default connect(mapStateToProps, mapStateToDispatch)(Home);
Cart.js
import React from 'react';
import { connect } from 'react-redux';
import { removeItem } from '../actions';
class Cart extends React.Component {
handleClick = (id) => {
this.props.removeItem(id);
}
renderList = () => {
if (this.props.addedItems.length !== 0) {
return this.props.addedItems.map(item => {
return (
<li className="collection-item avatar" key={item.id}>
<div className="item-img">
<img src={item.imageUrl} alt={item.name} style={{width: "120px"}} />
</div>
<div className="item-desc">
<span className="title">{item.name}</span>
<p>{item.content}</p>
<p><b>${item.price}</b></p>
</div>
<button
className="waves-effect waves-light btn pink remove"
onClick={this.handleClick(item.id)}
>Remove</button>
</li>
)
})
}
else {
return <p>Nothing is in cart.</p>
}
}
render() {
return (
<div className="container">
<div className="cart">
<ul className="collection">
{this.renderList()}
</ul>
</div>
</div>
)
}
}
const mapStateToProps = state => {
return { addedItems: state.cart.addedItems }
}
const mapDispatchToProps = dispatch => {
return {
removeItem: (id) => {dispatch(removeItem(id))}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Cart);
Header.js
import React from 'react';
import { Link } from 'react-router-dom';
const Header = () => {
return (
<nav className="nav-wrapper">
<div className="container">
<Link to="/" className="brand-logo">Shopping</Link>
<ul className="right">
<li><Link to="/">Shop</Link></li>
<li><Link to="/cart">Cart</Link></li>
<li><Link to="/cart"><i className="material-icons">shopping_cart</i></Link></li>
</ul>
</div>
</nav>
)
}
export default Header;
Reducers
import data from '../data.json';
import { ADD_TO_CART, REMOVE_FROM_CART } from "../actions/types";
const INITIAL_DATA = {
items: data,
addedItems: [],
total: 0
}
const cartReducer = (state = INITIAL_DATA, action) => {
switch(action.type) {
case ADD_TO_CART:
let addedItem = state.items.find(item => item.id === action.id);
let existedItem = state.addedItems.find(item => action.id ===item.id);
if (existedItem) {
addedItem.quantity += 1;
return {
...state,
total: state.total + addedItem.price
}
}
else {
addedItem.quantity = 1;
let newTotal = state.total + addedItem.price;
return {
...state,
addedItems: [...state.addedItems, addedItem],
total: newTotal
}
}
case REMOVE_FROM_CART:
let itemToRemove = state.addedItems.find(item => action.id === item.id);
let newItems = state.addedItems.filter(item => action.id !== item.id);
let newTotal = state.total - itemToRemove.price;
return {
...state,
addedItems: newItems,
total: newTotal
}
default:
return state;
}
}
export default cartReducer;
Actions
import { ADD_TO_CART, REMOVE_FROM_CART } from "./types";
export const addToCart = (id) => {
return {
type: ADD_TO_CART,
id
}
}
export const removeItem = (id) => {
return {
type: REMOVE_FROM_CART,
id
}
}
App.js
import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import Header from './Header';
import Home from './Home';
import Cart from './Cart';
const App = () => {
return (
<BrowserRouter>
<div className="app">
<Header />
<Switch>
<Route exact path="/" component={Home} />
<Route path="/cart" component={Cart} />
</Switch>
</div>
</BrowserRouter>
)
}
export default App;
Seems like you're actually calling your click handlers whenever you render your components, instead of just passing the handler function, so that's why actions are being triggered multiple times.
For instance, in your Home.js component change the code below from:
<span to="/" className="btn-floating halfway-fab waves-effect waves-light red" onClick={this.handleClick(item.id)} >
to:
<span to="/" className="btn-floating halfway-fab waves-effect waves-light red" onClick={() => { this.handleClick(item.id); }} >
And the same thing on Cart.js, change from:
<button className="waves-effect waves-light btn pink remove" onClick={this.handleClick(item.id)}>Remove</button>
to:
<button className="waves-effect waves-light btn pink remove" onClick={() => {this.handleClick(item.id); }}>Remove</button>
Related
I am receiving an error of Uncaught TypeError: cart.map is not a function
My cartSlice.js page:
import { createSlice } from "#reduxjs/toolkit";
const cartSlice = createSlice({
name: "cart",
initialState: {
cart: [],
},
reducers: {
addToCart: (state, action) => {
const itemInCart = state.cart.find(
(item) => item.id === action.payload.id
);
if (itemInCart) {
itemInCart.quantity++;
} else {
state.cart.push({ ...action.payload, quantity: 1 });
}
},
incrementQuantity: (state, action) => {
const item = state.cart.find((item) => item.id === action.payload);
item.quantity++;
},
decrementQuantity: (state, action) => {
const item = state.cart.find((item) => item.id === action.payload);
if (item.quantity === 1) {
item.quantity = 1;
} else {
item.quantity--;
}
},
removeItem: (state, action) => {
const removeItem = state.cart.filter(
(item) => item.id !== action.payload
);
state.cart = removeItem;
},
},
});
export const cartReducer = cartSlice.reducer;
export const { addToCart, incrementQuantity, decrementQuantity, removeItem } =
cartSlice.actions;
My store.js page (where I configure my store):
import { configureStore, combineReducers } from "#reduxjs/toolkit";
import { cartReducer } from "./cartSlice";
import appApi from "../services/appApi";
import storage from "redux-persist/lib/storage";
import {
persistReducer,
FLUSH,
REHYDRATE,
PAUSE,
PERSIST,
PURGE,
REGISTER,
} from "redux-persist";
import productReducer from "./productSlice";
import customerReducer from "./customerSlice";
import userReducer from "./userSlice";
import thunk from "redux-thunk";
import packageReducer from "./packageSlice";
const persistConfig = {
key: "root",
storage,
blackList: [appApi.reducerPath],
};
const rootReducer = combineReducers({
[appApi.reducerPath]: appApi.reducer,
products: productReducer,
customers: customerReducer,
cart: cartReducer,
user: userReducer,
packages: packageReducer,
});
const persistedReducer = persistReducer(persistConfig, rootReducer);
const store = configureStore({
reducer: persistedReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: {
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
},
}).concat(thunk, appApi.middleware),
});
export default store;
My index.js page (where I pass my store in the provider):
import React from "react";
import ReactDOM from "react-dom/client";
import { Provider } from "react-redux";
import store from "./redux/store";
import "./Admin/assets/css/App.css";
import { ChakraProvider } from "#chakra-ui/react";
import theme from "./Admin/theme/theme";
import { ThemeEditorProvider } from "#hypertheme-editor/chakra-ui";
import App from "./App";
import persistStore from "redux-persist/es/persistStore";
import { PersistGate } from "redux-persist/integration/react";
const persistedStore = persistStore(store);
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<ChakraProvider theme={theme}>
<React.StrictMode>
<ThemeEditorProvider>
<Provider store={store}>
<PersistGate loading={null} persistor={persistedStore}>
<App />
</PersistGate>
</Provider>
</ThemeEditorProvider>
</React.StrictMode>
</ChakraProvider>
);
My Cart.js page:
import Total from "../components/Shop/Total";
import CartItem from "../components/Shop/CartItem";
import { useSelector } from "react-redux";
import { Link, useNavigate } from "react-router-dom";
import Navbar from "../components/Shop/Navbar";
import Footer from "../components/Home/Footer";
function Cart() {
const cart = useSelector((state) => state.cart);
console.log(cart);
const user = useSelector((state) => state.user);
const navigate = useNavigate();
return (
<>
<div className="mb-5">
<Navbar />
</div>
<div className="cart">
<div className="cart__left">
<div>
<h3>Shopping Cart</h3>
{cart?.map((item) => (
<CartItem
key={item.id}
id={item.id}
name={item.name}
price={item.price}
quantity={item.quantity}
/>
))}
</div>
</div>
<div className="cart__right">
<Total />
{user ? (
<Link to="/checkout">
<button
className="btn btn-warning check-btn"
style={{ width: "20rem", padding: 10 }}
>
Procceed To Checkout <i class="bi bi-wallet2"></i>
</button>
</Link>
) : (
<Link to="/login">
<button
className="btn btn-warning check-btn"
style={{ width: "20rem", padding: 10 }}
onClick={() => navigate("/login")}
>
LogIn To Checkout <i class="bi bi-wallet2"></i>
</button>
</Link>
)}
</div>
</div>
</>
);
}
export default Cart;
My CartItem.js page:
import {
incrementQuantity,
decrementQuantity,
removeItem,
} from "../../redux/cartSlice";
import { useDispatch } from "react-redux";
function CartItem({ id, name, price, quantity = 0 }) {
const dispatch = useDispatch();
return (
<div className="cartItem">
<div className="cartItem__info">
<p className="cartItem__title">{name}</p>
<p className="cartItem__price">
<small>R</small>
<strong>{price}</strong>
</p>
<div className="cartItem__incrDec">
<button onClick={() => dispatch(decrementQuantity(id))}>-</button>
<p>{quantity}</p>
<button onClick={() => dispatch(incrementQuantity(id))}>+</button>
</div>
<button
className="cartItem__removeButton"
onClick={() => dispatch(removeItem(id))}
>
Remove
</button>
</div>
</div>
);
}
export default CartItem;
My Total.js page:
import { useSelector } from "react-redux";
function Total() {
const cart = useSelector((state) => state.cart);
const getTotal = () => {
let totalQuantity = 0;
let totalPrice = 0;
cart?.forEach((item) => {
totalQuantity += item.quantity;
totalPrice += item.price * item.quantity;
});
return { totalPrice, totalQuantity };
};
return (
<div className="total">
<h2 className="font-semibold fs-2">ORDER SUMMARY</h2>
<div>
<p className="total__p font-medium fs-5">
total ({getTotal().totalQuantity} products) :{" "}
<strong>R{getTotal().totalPrice}</strong>
</p>
</div>
</div>
);
}
export default Total;
I went to my shop page to try and add a product to my cart.
Shop.js page:
import React from "react";
import { motion } from "framer-motion";
import Navbar from "../components/Home/Navbar";
import Hero from "../components/Shop/Hero";
import ShopCard from "../components/Shop/ShopCard";
import { useNavigate } from "react-router-dom";
import { useSelector } from "react-redux";
const Shop = () => {
const products = useSelector((store) => store.products);
const navigate = useNavigate();
const ProductShop = () => (
<div className="shopping-cart" onClick={() => navigate("/cart")}>
<div className="bg-white">
{products?.map((product) => (
<div key={product.id}>
<ShopCard
name={product.name}
price={product.price}
desc={product.desc}
/>
</div>
))}
</div>
</div>
);
return (
<motion.div
id="main"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0, transition: { duration: 0.4 } }}
>
<Navbar />
<Hero />
{products?.length ? (
ProductShop()
) : (
<h1 className="fw-bold text-warning fs-3 text-center mt-3">
Products not availabe
</h1>
)}
</motion.div>
);
};
export default Shop;
My ShopCard.js page:
import React from "react";
import { useDispatch } from "react-redux";
import { addToCart } from "../../redux/cartSlice";
import { AiOutlineShoppingCart } from "react-icons/ai";
const ShopCard = ({ id, name, price, desc }) => {
const dispatch = useDispatch();
return (
<>
<section style={{ backgroundColor: "#eee" }}>
<div className="text-center container py-5">
<div className="column">
<div className="col-lg-4 col-md-12 mb-4">
<div className="card">
<div
className="bg-image hover-zoom ripple ripple-surface ripple-surface-light"
data-mdb-ripple-color="light"
>
<a href="#!">
<div className="hover-overlay">
<div
className="mask"
style={{ backgroundColor: "rgba(251, 251, 251, 0.15)" }}
></div>
</div>
</a>
</div>
<div className="card-body">
<h5 className="card-title mb-3 fw-bolder fs-3">{name}</h5>
<div className="mb-2 fs-5">
<h2>{desc}</h2>
</div>
<h6 className="mb-3 fw-bold fs-4">R{price}</h6>
<button
className="d-flex m-auto bg-warning text-white font-regular fs-5 align-items-center justify-content-center"
style={{ width: "100%", padding: 10 }}
type="button"
onClick={() => dispatch(addToCart({ id, name, price }))}
>
<AiOutlineShoppingCart fontSize={23} className="me-2" /> Add
to Cart
</button>
</div>
</div>
</div>
</div>
</div>
</section>
</>
);
};
export default ShopCard;
Then consoled log to see if it was working:
const cart = useSelector((state) => state.cart);
console.log(cart);
My consoled cart:
Object
cart
:
Array(1)
0
:
{name: 'Vegan Ham', price: '56', quantity: 4}
length
:
1
Its working but its not showing it up in my cart page. I have been trying to fix this problem for days now and I don't understand why it's not working.
The error is coming from this piece of code:
{cart?.map((item) => (
<CartItem
key={item.id}
id={item.id}
name={item.name}
price={item.price}
quantity={item.quantity}
/>
))}
Any help would be appreciated. Thanks
const cart = useSelector((state) => state.xyz.cart);
xyz is the key that you set in the store for the value of cartReducer in your store.
export const store = configureStore({
reducer: {
xyz: cartReducer,
},
})
how to add an action when the add button is clicked then the item will display the product?
This code does not display the product when clicked
I've been fiddling with it but it's still an error, who knows, someone here can help me and fix the code and explain it
cartAction.js
import {ADD_TO_CART} from './ActionType';
export const addToCart = (items) =>{
return{
type: ADD_TO_CART,
items //I'm confused about what to do in the action payload here
}
}
cartReducer.js
import ImgT from './images/image-product-1-thumbnail.jpg';
import {ADD_TO_CART} from './ActionType';
const initState = {
items: [
{id:1,title:'title',
brand:cc',
images:ImgT,
desc:'helo world',
price:125.00}
],addItems:[],
total:0
}
const cartReducer= (state = initState,action)=>{
if(action.type === ADD_TO_CART){
return {...state, addItems:state.addItems} //I'm confused about what to do in the action payload here
}
return state
}
export default cartReducer;
cart.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
class Cart extends Component {
render() {
return (
<div>
{this.props.Items.map(item =>{
<div key={item.id}>
{/* <img src={item.images} /> */}
<p>{item.title}</p>
<h4>brand: {item.brand}</h4>
<p>{item.price}</p>
</div>
})
}
</div>
);
}
}
const mapToProps = (state ) =>{
return{
Items:state.addItems}
}
export default connect(mapToProps)(Cart);
Home.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import Cart from './Cart';
import {addToCart} from './cartAction';
class Home extends Component{
handleClick = () =>{
this.props.addToCart()
}
render(){
let item = this.props.items.map(item =>{
return(
<div className='card' key={item}>
<img style={{width:'10rem'}} src={item.images}/>
<p className='card-title '>{item.title}</p>
<h2 className='card-title fs-4'>{item.brand}</h2>
<button onClick={() => this.handleClick()} className='btn btn-primary'>Add to cart</button>
<h3 className='fs-5'>{item.price}</h3>
</div>
)
})
return(
<div className="container">
<h3>Home</h3>
{item}
<Cart/>
</div>
)
}
}
const mapToProps = (state) => {
return{
items:state.items,
}
}
const mapDispatchToProps = (dispatch) => {
return{
addToCart: () => dispatch(addToCart())}
}
export default connect(mapToProps,mapDispatchToProps)(Home);
I am trying to implement a simple e-commerce application where I have a home component and a cart component whenever I call handle increment or handle decrement, quantity variable is increased or decreased twice in both cart array and items array.so {item.quantity} changes 0,2,4 and so on and this is happening on both cart page and home page. I feel like this has something to do with not using spread operator properly while updating an object in an array.
please help me understand why is this happening and how to resolve it.
Here is my code
shop.jsx
import React, { Component } from 'react';
import Navbar from './nav';
import Cart from './cart';
import Home from './home';
import { Switch, Route } from 'react-router-dom';
class Shop extends Component {
state = {
items: [],
cart: []
}
componentDidMount() {
let items = [...this.state.items];
items.push({ id: 1, name: "product1", price: 100, quantity: 0 });
items.push({ id: 2, name: "product2", price: 200, quantity: 0 });
this.setState({ items });
}
handleIncrement = (item) => {
console.log('handle increment called');
let items = [...this.state.items];
let cart = [...this.state.cart];
let productIndex = items.indexOf(item);
let cartIndex = cart.indexOf(item);
items[productIndex].quantity += 1;
if (cartIndex === -1) {
item.quantity += 1;
cart.push(item);
}
else {
cart[cartIndex].quantity += 1;
}
this.setState({ cart, items });
}
handleDecrement = (item) => {
console.log('handle decrement called');
let items = [...this.state.items];
let cart = [...this.state.cart];
let productIndex = items.indexOf(item);
let cartIndex = cart.indexOf(item);
items[productIndex].quantity -= 1;
cart[cartIndex].quantity -= 1;
this.setState({ cart, items });
}
render() {
return (
<div>
<Navbar />
<Switch>
<Route path="/home" render={(props) => <Home
items={this.state.items}
handleAdd={this.handleAdd}
handleIncrement={this.handleIncrement}
handleDecrement={this.handleDecrement}
{...props} />} />
<Route path="/cart" render={(props) => <Cart
cart={this.state.cart}
handleIncrement={this.handleIncrement}
handleDecrement={this.handleDecrement}
{...props} />} />
</Switch>
</div>
);
}
}
export default Shop;
Home.jsx
import React from 'react';
const Home = (props) => {
return (
<div>
Home
<ul>
{props.items.map((item) => {
return (
<li key={item.id}>
{item.name} <br />
{item.price} <br />
{
item.quantity === 0 ?
<button onClick={() => props.handleIncrement(item)}>add</button> :
<div>
<button onClick={() => props.handleDecrement(item)}>-</button>
<button>{item.quantity}</button>
<button onClick={() => props.handleIncrement(item)}>+</button>
</div>
}
</li>
)
})
}
</ul>
</div>
);
}
export default Home;
cart.jsx
import React from 'react';
const Cart = (props) => {
return (
<div>
cart
<ul>
{props.cart.map((item) => {
return (
<li key={item.id}>
{item.name} <br />
{item.price} <br />
{item.quantity} <br />
{item.price * item.quantity}
</li>
)
})}
</ul>
</div>
);
}
export default Cart;
nav.jsx
import React from 'react';
import { Link } from 'react-router-dom';
const Navbar = () => {
return (
<div>
Navbar
<Link to="/home">Home</Link>
<Link to="/cart">Cart</Link>
</div>
);
}
export default Navbar;
Remove items[productIndex].quantity += 1; from handleIncrement and items[productIndex].quantity -= 1; from handleDecrement method.
This will work.
import React, { Fragment, useEffect, useState } from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
import { getPosts } from '../redux/actions/#posts';
import PostItem from '../components/posts/PostItem';
import CommentForm from '../components/posts/CommentForm';
import Comment from '../components/posts/Comment';
import '../styles/posts/postComponent.scss';
const Posts = ({
getPosts,
posts: { posts, isLoading },
isAuthenticated,
user
}) => {
useEffect(() => {
getPosts();
}, []);
const [show, toggleShow] = useState(false);
console.log(show);
const postsList = isLoading ? (
<div>posts are loading</div>
) : (
posts.map(post => {
return (
<div className='post'>
<PostItem
key={post._id}
auth={isAuthenticated}
user={user}
id={post._id}
title={post.title}
body={post.text}
author={post.name}
avatar={post.avatar}
date={post.date}
likes={post.likes}
comments={post.comments.map(comment => comment)}
toggleShow={toggleShow}
show={show}
/>
<CommentForm id={post._id} />
{post.comments.map(
comment =>
show && (
<Comment
key={comment._id}
comment={comment}
auth={isAuthenticated}
admin={user}
show={show}
/>
)
)}
</div>
);
})
);
return (
<Fragment>
<Link to='/add-post'>add Post</Link>
<div>{postsList}</div>
</Fragment>
);
};
Posts.propTypes = {
getPosts: PropTypes.func.isRequired,
posts: PropTypes.object.isRequired,
isAuthenticated: PropTypes.bool.isRequired
};
const mapStateToProps = state => {
// console.log(state.posts.posts.map(post => post.likes));
// console.log(state);
return {
posts: state.posts,
isAuthenticated: state.auth.isAuthenticated,
user: state.auth.user
};
};
export default connect(mapStateToProps, { getPosts })(Posts);
import React, { Fragment } from 'react';
import '../../styles/posts/postComponent.scss';
const Comment = ({
comment: { user, avatar, name, date, text },
admin,
auth
}) => {
return (
<Fragment>
<div className='c-container'>
<div className='c-img-text'>
<img className='c-img' height={'40px'} src={avatar} />
<div className='c-nt'>
<a href='#' className='c-n'>
{name}
</a>
<span className='c-t'> {text}</span>
<i className='c-d'>{date}</i>
</div>
{auth && admin
? admin._id === user && <div className='c-toggle'>...</div>
: ''}
</div>
</div>
</Fragment>
);
};
export default Comment;
I have a list of posts stored in redux, and mapped through it to create components. Now each component has a some body and comments.
I want to show the comments only after onClick event .
Below is the code I have come up with , and on Click it is toggling all the comments of all the Components.How can I toggle comments of an individual Component.
I have a list of comments on soccer champions, and am trying to display comments of each soccer champion separately. I'm trying to order by id in firebase, but don't know how I can pass id from the champion component to the component where I display all the comments. It's just giving me undefined for some reason. Any help is greatly appreciated!
champ.js
import React, { Component } from "react";
import { ChampsRef, timeRef } from "./reference";
import { getsinglechamp } from "../actions/champs";
import { connect } from "react-redux"; // this is not being used. oh isee so like this?
import { Redirect, Link } from "react-router-dom";
import { Container, Row, Col } from "reactstrap";
import { Upvote } from "react-upvote";
import Form from "./Form";
import { Icon } from "react-icons-kit";
import Specials from "./specials";
import app from "../config/dev";
import { chevronDown } from "react-icons-kit/fa/chevronDown";
import { chevronUp } from "react-icons-kit/fa/chevronUp";
class OneChamp extends Component {
state = {
name: "",
weak: [],
img: "",
authenticated: false,
currentUser: null,
email: ""
};
componentDidMount() {
app.auth().onAuthStateChanged(user => {
if (user) {
this.setState({
currentUser: user,
email: user.email,
authenticated: true
});
} else {
this.setState({
currentUser: null,
authenticated: false
});
}
});
}
componentWillMount() {
const { dispatch, match } = this.props;
dispatch(getsinglechamp(match.params.id));
console.log(this.props);
}
render() {
console.log(this.props.champ);
const { dispatch, loading } = this.props;
const authenticated = this.state.authenticated;
console.log("change", this.props);
console.log("c", this.props.champ.img);
console.log("", this.props.champ.stats);
const champ = this.props.champ.stats;
let content = null;
if (loading) {
content = <p>Loading...</p>;
} else {
content = (
<div id="f">
<div className="ChampionHeader_row_ArTlM">
<div
style={{
paddingRight: "0.75rem",
paddingLeft: "0.75rem",
flexGrow: 1
}}
>
<div style={{ display: "flex", marginBottom: "1.5rem" }}>
<div style={{ flexShrink: 0, marginRight: "1rem" }}>
<div className="IconChampion_component_2qg6y IconChampion_lg_2QLBf">
<img
className="v-lazy-image v-lazy-image-loaded IconChampion_img_3U2qE"
src={this.props.champ.img}
height="80px"
/>
</div>
</div>
</div>
</div>
</div>
<div className="timeline-panel">
<div className="timeline-heading">
{" "}
<h4>{this.props.champ.name}</h4>
</div>
<ul>
{Object.keys(champ).map((item, i) => (
<div className="card">
<li className="travelcompany-input" key={i}>
<div> {champ[item]}</div>
</li>
</div>
))}
</ul>
<br />
<div className="w3-container">
// place i want to pass id <Comments id={this.props.champ.id} />
<h2>Weak To</h2> <br />
<ul className="w3-ul w3-card-4">
<li className="w3-bar">
<img
src={this.props.champ.img2}
className="w3-bar-item w3-circle w3-hide-small"
style={{ width: 145 }}
/>
<div className="w3-bar-item">
<span className="w3-large">{this.props.champ.weak}</span>
<br />
<span id="item"> Mid </span>
<div className="col-sm-5">
<span className="label label-primary">
{this.props.champ.win}
</span>
</div>
</div>
</li>
<li className="w3-bar">
<img
src={this.props.champ.img3}
className="w3-bar-item w3-circle w3-hide-small"
style={{ width: 145 }}
/>
<div className="w3-bar-item">
<Link to={`/Matchup/${this.props.champ.id}`}>
{" "}
<span className="w3-large">{this.props.champ.weak3}</span>
<br />{" "}
</Link>
<span id="item"> Mid </span>
<span className="label label-primary">
{this.props.champ.win}
</span>
</div>
</li>
</ul>
</div>
</div>
<div />
{authenticated ? (
<div className="nav-item">
<Form id={this.props.champ.id} />
</div>
) : (
<div className="nav-item">
<Link to="/login" className="nav-link2">
{" "}
Login to post
</Link>
</div>
)}
</div>
);
}
return <div>{content}</div>;
}
}
const mapStateToProps = state => {
console.log("champs", state.champs);
console.log(state.loading);
return {
champ: state.champs.champ,
loading: state.loading
};
};
export default connect(
mapStateToProps,
null
)(OneChamp);
comments.js
import React, { Component } from "react";
import axios from "axios";
import app from "../config/dev";
import { Link } from "react-router-dom";
import { ChampsRef, CommentsRef, timeRef } from "./reference";
import { connect } from "react-redux";
import { getsinglechamp } from "../actions/champs";
class Comments extends Component {
state = {
comments: [],
champ_id: "",
loading: true,
email: ""
};
componentWillMount() {
const champ_id = this.props.champ.id;
console.log("id", this.props.champ);
CommentsRef.orderByChild("champ_id")
.equalTo(`${champ_id}`)
.on("value", snap => {
const tasks = [];
let comments = [];
snap.forEach(child => {
comments.push({ ...child.val(), key: child.key });
});
this.setState({ comments: comments, Loading: false });
});
}
render() {
const { dispatch, loading } = this.props;
const { comments, ChampsLoading } = this.state;
const orderedchamps = comments;
let commentList;
if (ChampsLoading) {
commentList = <div className="TaskList-empty">Loading...</div>;
} else if (comments.length) {
commentList = (
<ul className="TaskList">
{comments.map(comment => (
<div>{comment.text}</div>
))}
</ul>
);
}
return (
<div>
<h1> Popular Cham</h1>
<p> {commentList} </p>
</div>
);
}
}
const mapStateToProps = state => {
console.log("champs", state.champs);
console.log(state.loading);
return {
champ: state.champs.champ,
loading: state.loading
};
};
export default connect(
mapStateToProps,
null
)(Comments);