I have made a simple shopping cart using React.js. I am using localStorage to store the state value so that even after the refresh, the values remain in the UI.
Also, does modifying the Items content through states, change the
original Items content?
Following are the different files that I am using to render:
ShoppingCart.js
import React, { Component } from 'react';
import { Table, Button, Media, Card, CardHeader, CardBody, CardFooter } from 'reactstrap';
import Items from '../shared/Items';
class ShoppingCart extends Component {
constructor(props) {
super(props);
this.state = {
items: JSON.parse(localStorage.getItem("items")) || Items
}
}
decreaseQuantity = (item) => {
const copy = this.state.items;
item.quantity -= 1;
for(let i = 0; i < copy.length; i++) {
if(copy[i].id === item.id)
copy[i] = item;
}
localStorage.setItem("items", JSON.stringify(copy));
this.setState({
items: copy
});
};
increaseQuantity = (item) => {
const copy = this.state.items;
item.quantity += 1;
for(let i = 0; i < copy.length; i++) {
if(copy[i].id === item.id)
copy[i] = item;
}
localStorage.setItem("items", JSON.stringify(copy));
this.setState({
items: copy
});
};
resetCart = () => {
localStorage.setItem("items", JSON.stringify(Items));
this.setState({
items: Items
})
};
removeItem = (item) => {
let copy = this.state.items;
copy.splice(copy.indexOf(item), 1);
localStorage.setItem("items", JSON.stringify(copy));
this.setState({
items: copy
});
}
render() {
const array = this.state.items;
const total = array.reduce((acc, item) => acc + item.quantity, 0);
let typeDiscount = 0;
let normalDiscount = 0;
const totalPrice = array.reduce((acc, item) => {
normalDiscount += ((item.quantity * item.price) * item.discount) / 100;
if (item.type === "fiction")
typeDiscount += ((item.quantity * item.price) * 15) / 100;
return acc + (item.quantity * item.price);
}, 0);
const items = array.map((item) => (
<tr key={item.id}>
<td>
<Media>
<Media left className="mr-3">
<Media object data-src={item.img_url} style={{height: 20, width: 20}} placeholder={item.name} />
</Media>
<Media body>
{item.name}
<Button close onClick={() => this.removeItem(item)} />
</Media>
</Media>
</td>
<td>
<Button color="danger" className="mr-3" disabled={item.quantity === 1}
onClick={() => this.decreaseQuantity(item)}>
-
</Button>
{item.quantity}
<Button color="success" className="ml-3" onClick={() => this.increaseQuantity(item)}>+</Button>
</td>
<td>{item.quantity * item.price}</td>
</tr>
));
return (
<React.Fragment>
<div className="container">
<div className="row">
<div className="col-md">
<Table>
<thead>
<tr>
<th>Item({total})</th>
<th>Qty</th>
<th>Price</th>
</tr>
</thead>
<tbody>
{items}
</tbody>
</Table>
</div>
<div className="col-md">
<Card>
<CardHeader>Total</CardHeader>
<CardBody>
<dl className="row p-1">
<dt className="col-6">Items({total})</dt>
<dd className="col-6">{totalPrice}</dd>
<br />
<dt className="col-6">Discount</dt>
<dd className="col-6">{normalDiscount}</dd>
<dt className="col-6">Type Discount</dt>
<dd className="col-6">{typeDiscount}</dd>
</dl>
</CardBody>
<CardFooter>
<dl className="row p-1">
<dt className="col-6">Order Total</dt>
<dd className="col-6">{totalPrice - normalDiscount - typeDiscount}</dd>
</dl>
</CardFooter>
</Card>
</div>
</div>
</div>
<br /><br />
<Button style={{position: "absolute", right: 500}} color="primary" className="mt-5" onClick={this.resetCart}>Reset</Button>
</React.Fragment>
);
}
}
export default ShoppingCart;
App.js
import React from 'react';
import ShoppingCart from './components/ShoppingCart';
function App() {
return (
<div className="mt-5">
<ShoppingCart />
</div>
);
}
export default App;
Index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import * as serviceWorker from './serviceWorker';
import 'bootstrap/dist/css/bootstrap.min.css';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
serviceWorker.unregister();
Items.js
//The JSON file containing the items data
const Items = [{ "id": 9090, "name": "Item1", "price": 200, "discount": 10, "type": "fiction", "img_url": "https://place-hold.it/40.jpg", "quantity": 1 },
{ "id": 9091, "name": "Item2", "price": 250, "discount": 15, "type": "literature", "img_url": "https://place-hold.it/40.jpg", "quantity": 1 },
{ "id": 9092, "name": "Item3", "price": 320, "discount": 5, "type": "literature", "img_url": "https://place-hold.it/40.jpg", "quantity": 1 },
{ "id": 9093, "name": "Item4", "price": 290, "discount": 0, "type": "thriller", "img_url": "https://place-hold.it/40.jpg", "quantity": 1 },
{ "id": 9094, "name": "Item5", "price": 500, "discount": 25, "type": "thriller", "img_url": "https://place-hold.it/40.jpg", "quantity": 1 },
{ "id": 9095, "name": "Item6", "price": 150, "discount": 5, "type": "literature", "img_url": "https://place-hold.it/40.jpg", "quantity": 1 },
{ "id": 9096, "name": "Item7", "price": 700, "discount": 22, "type": "literature", "img_url": "https://place-hold.it/40.jpg", "quantity": 1 },
{ "id": 9097, "name": "Item8", "price": 350, "discount": 18, "type": "fiction", "img_url": "https://place-hold.it/40.jpg", "quantity": 1 }];
export default Items;
I tried running the app, but I kept on getting the following error:
Error: A cross-origin error was thrown. React doesn't have access to the actual error object in development.
Can someone help me with this? What am I doing wrong ?
Related
Iam trying to map a array of objects in my react js app i am getting my response using redux which is true the problem is whenever iam using mapstatetoprops and mapDispatchtoprops it is not mapping my props into the state due to which iam getting undefined in my console other than that iam unable to map nested array response i want to get value which is inside of inputOptions how can i fix these issues.
My component
import React, { Component } from "react";
import {
FormCardComponent,
TextInputComponent,
RadioInputComponent,
SelectComponent,
} from "../../components/index";
import IntlMessages from "../../common/constants/IntlMessages";
import frontPage from "./dummy";
import { TopBar } from "../../layouts/authLayout/components/index";
import { getEmsForms } from "../../redux/action/categories";
import { bindActionCreators } from "redux";
import { connect } from "react-redux";
import { Form } from "./form";
class DummyForm extends Component {
constructor(props) {
super(props);
this.state = {
field: "",
checkBox: "",
options: "",
radioField: "",
error: "",
data: frontPage,
};
}
componentDidMount() {
this.props.getEmsForms()
}
render() {
console.log('COMP',JSON.stringify(this.props.getEmsForms()));
return (
<React.Fragment>
<div className="col" style={{ marginTop: "50px" }}>
<React.Fragment>
<TextInputComponent
style={{ marginTop: "50px" }}
label={<IntlMessages id="profile.personal.field.name" />}
type="text"
placeholder={"Abdul"}
value={this.state.name}
onChange={(e) =>
this.setState({ name: e.target.value, error: "" })
}
/>
<select
className="custom-select"
id="inputGroupSelect01"
style={{ marginTop: "50px" }}
>
<option>
{/* {value.MinimumAge} */}
yes
</option>
<option>
{/* {value.MinimumAge} */}
yes
</option>
</select>
<div style={{ marginTop: "50px" }}>
<SelectComponent
style={{ marginTop: "50px" }}
name={"select2"}
value={this.state.select2}
label={
"Jeg vil gerne modtage en SMS når der er nyheder til mig"
}
onChange={(e) => this.setState({ select2: e.target.checked })}
/>
</div>
<div style={{ marginTop: "50px" }}>
{/* <RadioInputComponent
title="gender"
value={this.state.gender}
name={["male", "female", "other"]}
onChange={(e) => {
this.setState({ gender: e.target.value, error: "" });
}}
/> */}
<input
style={{
float: "left",
clear: "none",
margin: "3px",
}}
type="radio"
/>
<label style={{ padding: " 0px 1em 0px 8px" }}>
Jeg vil gerne modtage en SMS når der er nyheder til mig
</label>
</div>
<div className="row" style={{ marginTop: "50px" }}>
<div className="col d-flex justify-content-start">
<button className="btn-danger" onClick={this.toggleModal}>
Ja
</button>
</div>
<div className="col d-flex justify-content-end">
<button className="btn btn-success button-margin">Ja</button>
</div>
</div>
</React.Fragment>
</div>
</React.Fragment>
);
}
}
const mapStateToProps = (data) => ({
// user: data.authenticateUser.user,
// isAuthenticated: data.authUser,
getForms: data.categories.getForms,
});
const mapDispatchToProps = (dispatch) =>
bindActionCreators(
{
getEmsForms,
},
dispatch
);
export default connect(mapStateToProps, mapDispatchToProps)(DummyForm);
My Api Response
{
"success": true,
"messages": "EMS Form",
"data": [
{
"question_id": 3,
"fieldName": "FirstName",
"order": 0,
"isRequired": true,
"isShown": true,
"isEditable": false,
"fieldLabelText": "First Name da",
"errorText": "First Name Error da",
"inputType": "textbox",
"inputOptions": [],
"inputOptionsCustom": []
},
{
"question_id": 4,
"fieldName": "LastName",
"order": 1,
"isRequired": true,
"isShown": true,
"isEditable": false,
"fieldLabelText": "First Name da",
"errorText": "First Name Error da",
"inputType": "textbox",
"inputOptions": [],
"inputOptionsCustom": []
},
{
"question_id": 2,
"fieldName": "Age",
"order": 2,
"isRequired": true,
"isShown": true,
"isEditable": false,
"fieldLabelText": "First Name da",
"errorText": "First Name Error da",
"inputType": "dropdown",
"inputOptions": [
{
"option_id": 7,
"text": "18",
"value": "18"
},
{
"option_id": 8,
"text": "19",
"value": "19"
},
{
"option_id": 9,
"text": "20",
"value": "20"
},
{
"option_id": 10,
"text": "21",
"value": "21"
},
{
"option_id": 11,
"text": "22",
"value": "22"
},
{
"option_id": 12,
"text": "23",
"value": "23"
}
],
"inputOptionsCustom": []
},
{
"question_id": 5,
"fieldName": "PhoneNumber",
"order": 3,
"isRequired": false,
"isShown": true,
"isEditable": false,
"fieldLabelText": "First Name da",
"errorText": "First Name Error da",
"inputType": "textbox",
"inputOptions": [],
"inputOptionsCustom": []
}
]
}
my action
export const getEmsForms = (data) => {
return async (dispatch) => {
dispatch(fullScreenLoader(true));
const api = new Axios();
let token = getToken();
console.log('token', JSON.stringify(token))
const response = await api.post(
GET_EMS_FORMS,
{
ems_id: EMS_ID,
},
{
Authorization: `Bearer ${token}`,
},API_URL2
);
// console.log(response);
console.log('res', JSON.stringify(response))
const { data } = response;
dispatch(fullScreenLoader(false));
dispatch({
type: GET_FORMS ,
payload: data,
});
};
};
my reducer
case GET_FORMS:
return {
...state,
forms: action,
};
You are trying to access data.categories.getForms, but in your reducer you are mapping it to forms. Also you want to set the action.payload to .forms and not the whole action.
So you reducer needs to look like this:
case GET_FORMS:
return {
...state,
forms: action.payload,
};
and your mapStateToProps
const mapStateToProps = (data) => ({
user: data.authenticateUser.user,
isAuthenticated: data.authUser,
forms: data.categories.forms,
});
I am working on a list app, and I am having issues with the components not updating correctly. I pull the users list from a JSON file and save it in a state. I am using context to pass that state and other information around to my different compoents. The smallest component is the user items broken out into a list which is editable. It is here with the list of items that I am having issues with.
For example, I have two different JSON files:
[{"userId": 81944,
"listId": 1,
"title": "testa",
"items": [
{
"listItemId": 0,
"product": "walnuts",
"quantity": 1,
"category": "Bakery",
"unit": "Each",
"cart": false
},
{
"listItemId": 1,
"product": "syrup",
"quantity": 1,
"category": "Beverages",
"unit": "Each",
"cart": true
},
{
"listItemId": 2,
"product": "cinnamon",
"quantity": 6,
"category": "Bakery",
"unit": "Each",
"cart": false
},
{
"listItemId": 3,
"product": "gabonzo beans",
"quantity": 1,
"category": "Canned Goods",
"unit": "Each",
"cart": true
},
{
"listItemId": 4,
"product": "diced tomatos",
"quantity": 7,
"category": "Produce",
"unit": "Each",
"cart": false
},
{
"listItemId": 5,
"product": "milk",
"quantity": 1,
"category": "Dairy",
"unit": "Oz",
"cart": false
},
{
"listItemId": 6,
"product": "salmon",
"quantity": 3,
"category": "Meat",
"unit": "Lb",
"cart": false
}]},{
"userId": 78863,
"listId": 4,
"title": "testd",
"items": [
{
"listItemId": 0,
"product": "half and half",
"quantity": 1,
"category": "Dairy",
"unit": "Each",
"cart": false
},
{
"listItemId": 1,
"product": "Blue Cheese",
"quantity": 1,
"category": "Dairy",
"unit": "Each",
"cart": false
},
{
"listItemId": 2,
"product": "Garlic",
"quantity": 1,
"category": "Produce",
"unit": "Each",
"cart": false
},
{
"listItemId": 3,
"product": "Chestnuts",
"quantity": 1,
"category": "Other",
"unit": "Each",
"cart": false
},
{
"listItemId": 4,
"product": "Balsamic Vinegar",
"quantity": 1,
"category": "Other",
"unit": "Each",
"cart": false
},
{
"listItemId": 5,
"product": "Onions",
"quantity": 1,
"category": "Produce",
"unit": "Each",
"cart": false
},
{
"listItemId": 6,
"product": "Flax Seed",
"quantity": 1,
"category": "others",
"unit": "Each",
"cart": false
},
{
"listItemId": 7,
"product": "Plantains",
"quantity": 1,
"category": "Produce",
"unit": "Each",
"cart": false
}]}]
In my app I have a dialog box that allows me to switch between my lists. I then take list and pass it a custom component to be drawn on the screen.
import React, {useState,useEffect} from 'react';
const Card=(props)=>{
//console.log('prop');
const [cart, setCart] = useState(props.cart);
const [Product, setProduct] = useState(props.item);
const [Quantity, setQuantity] = useState(props.units);
// useEffect(()=>{
// setProduct(props.item)
// setQuantity(props.units)
// setCart(props.cart);
// },[])
console.log(props)
return (
<li key={props.value}>
<div>
<input type="checkbox" checked={cart} onChange={(e)=>{props.cartChange(e.target)}}/>
</div>
<div>
<input id={'product '+props.value} className='update'
type='text' value={Product}
onChange={(e)=>setProduct(e.target.value)}
/>
<br/>
<input id='quantityValue' className='update'
type='number' value={Quantity}
onChange={(e)=>setQuantity(e.target.value)}
/>
<span id='quantityType' className='update'>{props.unitType}</span>
</div>
<div>
<button id='save-button' type='button'
onClick={(e)=>{props.change(Product,Quantity,props.value)}}>✓ save</button>
<button id='delete-button' type='button'>✗ delete</button>
</div>
</li>
)
}
export default Card;
This is the code that calls the custom components. You will see that I am calling it from a array.map() those arrays are fine, and have the correct information in them.
import React, {useContext,useEffect} from 'react';
import {DataContext} from '../../../context/test/DataContext'
import Card from './ItemCard';
const update=(x)=>{
console.log(x)
}
const List = () =>{
const {listId} = useContext(DataContext);
const {userItemList} = useContext(DataContext);
const {GetItemList} = useContext(DataContext);
const {ListSplit} = useContext(DataContext);
const {foundList} = useContext(DataContext);
const {findList} = useContext(DataContext);
const {Updater} = useContext(DataContext);
const {cartUpdater} = useContext(DataContext);
useEffect(()=>{
GetItemList();
},[listId])
useEffect(()=>{
ListSplit();
},[userItemList])
// console.log(findList);
// console.log(foundList);
return(
<div>
<p>To find:</p>
<ul>
{findList.map((item,index)=><Card key={item.listItemId} index={index}
value={item.listItemId} cart={item.cart} item={item.product}
units={item.quantity} unitType={item.unit}
cartChange={cartUpdater} change={Updater} />)}
</ul>
<p>Found:</p>
<ul>
{foundList.map((item,index)=><Card key={item.listItemId} index={index}
value={item.listItemId} cart={item.cart} item={item.product}
units={item.quantity} unitType={item.unit}
cartChange={cartUpdater} change={Updater} />)}
</ul>
</div>
)
}
export default List;
Each time I switch this, the props that I console log out change correctly. Also, if I look at my compoents in dev tools (chrome) I see that the states should be correct, however what I see on the screen is not correct. For example the second item which is cinnamon, if I switch to the second list should be Blue Cheese. The prop changes, as does the state, but what I see on the screen is still cinnamon.
I know that I probably didnt explain it that clearly, but below is a screen shot of what I am talking about.
You were close with the commented out code. Since you are setting your props to state (which is a bad idea and I will discuss at the bottom), your useState only sets the state initially. You want to watch these props and update when they do.
useEffect(() => {
setProduct(props.item)
setQuantity(props.units)
setCart(props.cart);
}, [props.item, props.units, props.cart]);
The items in the array are what useEffect watches to know if it should fire.
As a side note - assigning props to state is a bad idea and you've seen why - they don't automatically update. You should hoist up where these props are set to the parent and you can pass them down as props and use them directly. You can pass down the setters as props as well, which can update the parent.
This article, while referencing class based React component may provide more information if you'd care to read up on it.
const { useState } = React;
const initialItems = [
{
listItemId: 1,
product: 'syrup',
quantity: 1,
category: 'Beverages',
unit: 'Each',
cart: true,
},
{
listItemId: 2,
product: 'cinnamon',
quantity: 6,
category: 'Bakery',
unit: 'Each',
cart: false,
},
{
listItemId: 3,
product: 'garbanzo beans',
quantity: 1,
category: 'Canned Goods',
unit: 'Each',
cart: true,
},
];
const Parent = () => {
const [items, setItems] = useState(initialItems);
const updateProduct = listItemId => (e) => {
setItems(items.map((item) => {
if (item.listItemId === listItemId) {
return { ...item, product: e.target.value };
}
return item;
}));
};
const updateQuantity = listItemId => (e) => {
setItems(items.map((item) => {
if (item.listItemId === listItemId) {
return { ...item, quantity: e.target.value };
}
return item;
}));
};
return (
<div>
<div style={{ width: "50%" }}>
All Items - (this state lives inside the parent component)
</div>
<div>
{items.map(item => (
<div>
<div>
Product - {item.product}
</div>
<div>
Quantity - {item.quantity}
</div>
</div>
))}
</div>
<div style={{ width: "50%" }}>
{items.map(item => (
<Child item={item} updateQuantity={updateQuantity} updateProduct={updateProduct} />
))}
</div>
</div>
);
};
const Child = ({ item, updateQuantity, updateProduct }) => {
return (
<div>
<div>
<span>
Product -
</span>
<span>
<input value={item.product} onChange={updateProduct(item.listItemId)} />
</span>
</div>
<div>
<span>
Quantity -
</span>
<span>
<input value={item.quantity} onChange={updateQuantity(item.listItemId)} />
</span>
</div>
</div>
);
};
ReactDOM.render(
<Parent />,
document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
A little example above. The parent component holds the state of the items and maps over each to create a child component. This example is a little rough around the edges. You could do something like adding data-id and name to each input to simplify the updating functions, or use useReducer to hoist that logic a bit, but I think it gets you going in the right direction.
I'm sweeping a JSON and grabbing the value of a snack.
{
"lanches": [
{
"id": 1,
"name": "X-Bacon",
"ingredients": [
"Bacon",
"Hambúrguer",
"Queijo"
],
"initialValue: 9.00
}
]
}
I need to show it when the system starts .. so far okay.
I have a list of additional items that is another JSON swept.
{
"ingredientes": [
{
"id": 1,
"name": "Alface",
"price": 0.40
},
{
"id": 2,
"name": "Bacon",
"price": 2.00
},
{
"id": 3,
"name": "Hambúrguer de carne",
"price": 3.00
},
{
"id": 4,
"name": "Ovo",
"price": 4.00
},
{
"id": 5,
"name": "Queijo",
"price": 5.00
}
]
}
When you add each item, you need to add up with the initial value. I can add only the added items. I can not add the first value and add it with the items.
Here is where I sweep the JSON to pick up the snacks
{this.state.lanches.map(lanche => (
<div className="item" key={lanche.id}>
<div className="item__desc--top">
<h2 className="item__title">{lanche.name}</h2>
<p className="item__price">{this.state.totalPrice}</p>
</div>
<ul className="item__ingredientes">
{lanche.ingredients.map(ingredientes =>
<li className="item__ingredientes--itens" key={ingredientes}>
<span>{ingredientes}</span>
{ this.state.editItem ? <button className="actionRemove"><i className="fa fa-times"></i></button> : null}
</li>
)}
</ul>
<p className="itens__adicionais">Add Items</p>
<ul className="itens__adicionais--menu">
{this.state.ingredientes.map(ingrediente =>
<li className="itens__adicionais--item" key={ingrediente.id}>
<span>{ingrediente.name}</span>
<button className="actionAdd" onClick={((e) => this.handleAdd(e, ingrediente.price, lanche.price))}><i className="fa fa-plus"></i></button>
</li>
)}
</ul>
</div>
))}
And here is the function of summing the value:
handleAdd = (e, value_ingrediente) => {
this.setState(
{
totalPrice: this.state.totalPrice + value_ingrediente
}
)
}
The JSON backend guys provide me its multiple parent child so I have to put the dynamic loop to show parent child.
JSON
"data": [
{
"id": 25,
"slug": "mobiles",
"parent_id": null,
"name": "Mobiles"
},
{
"id": 26,
"slug": "mobile-phones-accessories",
"parent_id": 25,
"name": "Mobile Phones accessories"
},
{
"id": 27,
"slug": "computer-laptop",
"parent_id": null,
"name": "Computer & Laptop"
},
{
"id": 28,
"slug": "laptops",
"parent_id": 27,
"name": "Laptops"
},
{
"id": 29,
"slug": "mobile-phones",
"parent_id": 26,
"name": "Mobiles Phone"
}
]
My Function (Kindly ignore this. It's just a try but I have got 1 child parent)
renderCategoriesHtml() {
const { categories } = this.props;
if (!categories) return false;
const nullCat = [];
categories.map((obj) => {
if (obj.parent_id == null) {
nullCat.push(obj);
}
});
return nullCat.map(
(parentCat, i) => (
<div className="form-group" key={i}>
<div className="checkbox" key={i}>
<label>
<Field
name={`categories.${parentCat.id}`}
component="input"
type="checkbox"
/>
{parentCat.slug}
</label>
</div>
{
categories.map(
(childCat, j) => (
parentCat.id == childCat.parent_id ?
<div className="checkbox ml-20" key={j}>
<label>
<Field
name={`categories.${childCat.id}`}
component="input"
type="checkbox"
/>
{childCat.slug}
</label>
</div>
: ''
)
)
}
</div>
)
);
}
I want this (That dynamic html i want)
<ul>
<li>mobiles</li>
<ul>
<li>mobile-phones-accessories</li>
<ul>
<li>mobile-phones</li>
</ul>
</ul>
<li>computer-laptop</li>
<ul>
<li>laptops</li>
</ul>
</ul>
Try this:
class TreeRender extends React.Component {
state = {
data: JSON.parse('[{"id": 25,"slug": "mobiles","parent_id": null,"name": "Mobiles"},{"id": 26,"slug": "mobile-phones-accessories","parent_id": 25,"name": "Mobile Phones accessories"},{"id": 27,"slug": "computer-laptop","parent_id": null,"name": "Computer & Laptop"},{"id": 28,"slug": "laptops","parent_id": 27,"name": "Laptops"},{"id": 29,"slug": "mobile-phones","parent_id": 26,"name": "Mobiles Phone"}]')
}
getCurrent = (node) => this.state.data.filter(cNode => cNode.parent_id == node).map(cNode => (
<ul key={`node_${cNode.id}`}>
<li>{cNode.name}</li>
{this.getCurrent(cNode.id)}
</ul>
))
render() {
return (
<div>
{this.getCurrent(null)}
</div>
);
}
}
FIDDLE
I have an app that shows a graph by date and brand. Unfortunately I'm new to react and recharts and i dont know how to get the specific data that I want.
For now I am using an area chart
as for my data
const data1 = [
{
"data1result": [
{
"brand": "brand1"
},
{
"brand": "brand2"
},
{
"brand": "brand3"
},
{
"brand": "brand4"
}
]
}
];
const data2 = [
{
"data2result": [
{
"date": "12-01",
"details": [
{
"amount": 24250,
"brand": "brand1"
},
{
"amount": 68350,
"brand": "brand2"
},
{
"amount": 60,
"brand": "brand3"
},
{
"amount": 11078,
"brand": "brand4"
}
]
},
{
"date": "12-02",
"details": [
{
"amount": 27340,
"brand": "brand1"
},
{
"amount": 16500,
"brand": "brand2"
},
{
"amount": 210,
"brand": "brand3"
},
{
"amount": 23229,
"brand": "brand4"
}
]
},
{
"date": "12-03",
"details": [
{
"amount": 24250,
"brand": "brand1"
},
{
"amount": 68350,
"brand": "brand2"
},
{
"amount": 60,
"brand": "brand3"
},
{
"amount": 11078,
"brand": "brand4"
}
]
}
]
}
];
and for my code
export default React.createClass({
render() {
return (
<ResponsiveContainer width="100%" aspect={3}>
<AreaChart width={600} height={400} data={data}
margin={{top: 10, right: 30, left: 0, bottom: 0}}>
<XAxis height={60} tick={<CustomizedAxisTick/>} dataKey="name"/>
<YAxis/>
<CartesianGrid strokeDasharray="3 3"/>
<Tooltip/>
{data1[0].data1result.map(function(c, index) {
return (
<Area type='monotone' dataKey={c.name} stroke={colors[index % colors.length]} fill={colors[index % colors.length]} fillOpacity={0.3}/>
)
})}
<Legend/>
</AreaChart>
</ResponsiveContainer>
)}
})
and output should be like this
You need to construct your data as 0-indexed array of objects.
let graphData = [
{
date: "12-01",
brand1: 24250,
brand2: 68350,
brand3: 60,
brand4: 11078,
},
{
date: "12-02",
brand1: 27340,
brand2: 16500,
brand3: 210,
brand4: 23229,
},
{
date: "12-03",
brand1: 24250,
brand2: 68350,
brand3: 60,
brand4: 11078,
}]
And your component will look like this
export default React.createClass({
_drawAreas(){
let data = this.state.data || [];
let dataSet = data[0], areaArr = [];
let count = 0, len = Object.keys(dataSet).length;
let colorCodes = ["#17607D", "#F2D8A7", "#1FCECB", "#FF9311", "#003D5C", "#F27649", "#D5CDB6", "#008C74", "#30588C", "#263138"]
for(let i in dataSet){
if(dataSet.hasOwnProperty(i) && i != 'date'){
areaArr.push(<Area type='monotone' dataKey={i} stroke={colorCodes[count]} key={`area-chart-${count}`} fill={colorCodes[count]}/>)
count++;
}
}
return areaArr;
}
render() {
return (
<ResponsiveContainer width="100%" aspect={3}>
<AreaChart width={600} height={400} data={this.state.data}
margin={{top: 10, right: 30, left: 0, bottom: 0}}>
<XAxis height={60} dataKey="date"/>
<YAxis/>
<CartesianGrid strokeDasharray="3 3"/>
<Tooltip/>
{this._drawAreas()}
<Legend/>
</AreaChart>
</ResponsiveContainer>
)} })