Manipulation state and a few questions on rendering and architecture in react?

Hello! Did not want to ask for help, for himself, but because of the lack of the necessary knowledge forced to give up and to write here

Learn react, and decided to create a kind of Internet store based on data obtained from API, but paused for some moments

The app works on this principle:
Loading data from API, the data is loaded in state = { result: [] }, then will render the data, pulling the data from the state and passing them through the component (which is stylized data). In the end we have page 25 of stylized components with data and I want when you click on this component it was added to cart state = { basket: [] } .
That's how it looks
spoiler
5c9c0d07857c2335234651.jpeg

Now to the code (which I slightly simplify, leaving the basic functionality) and then to the problems and questions

Component of the styling (probably will hurt the eyes, sorry)
spoiler
const NewsItem = ({ styles, id, name, tagline, abv, image, clickFilter } ) => (
the <div>
 <ul className={styles}>
 <p> <img src={image} alt="empty"
 height='150'></img> </li>
 the <li> {`ID ${id}`} </li>
 the <li> {`Name - ${name}`} </li>
 the <li> {`Tag - ${tagline}`} </li>
 the <li> {`Fortress - ${abv}`} </li>
the <li>
 <button onClick={clickFilter}>add to cart</button> //when this button is clicked, add to cart
 </li> 
</ul>
</div>
);


The main file
spoiler
const BASE_PATH = 'https://api.punkapi.com/v2/beers';

class Store extends Component {
 state = {
 result: [],
buy:[],
}

componentDidMount() { 
 fetch(`${BASE_PATH}`) 
 .then(res => res.json()) //this works
 .then(result => this.setItem(result))
 .catch(error => error); 
}

setItem = result => { 
 this.setState( {result} ); 
}

render() {

 const { result } = this.state;

 return (
 the <div> 
 the <ul >
 {result.map(({ id, name, tagline, abv, description, image_url}) => // the extrusion obtained 
 <NewsItem key={id} // API data and their stylization
 styles={'item'} 
 image={image_url} // NewsItem component to style
id={id}
name={name}
tagline={tagline}
 abv = {abv}
 // clickFilter = {here we need a method implementation to add to cart} 
/>
)}
 </ul> 
</div>
)
}


And now the questions:

1. How to add received "goods" in the basket? I couldn't use the values of the state.result for subsequent adding of state.basket.
the result is just an array of objects. It is possible to access any product by using this.state.result[indexobject], but nothing with this data directly to do not I like using setState

2. The question stems from 1st, and whether it is normal practice to add to state data received from the API? If not, then where can they be stored?

3. I wanted to create each "item" button, which will change the style of this particular product (it does not carry any meaning, but I wanted to implement it to understand some things).
My component has NewsItem props styles, which sets the style to the component.
const NewsItem = ({ styles ...all other props}) => (
 the <div >
 <ul className={styles}>
...code on
 </div>

I tried to change the className={ something === true ? 'class1' : 'class2' }
Created a button with onClick handler = { something === false } . This is pseudo code, but the meaning is clear
In the end, the maximum that at me turned out, this change of style ALL the goods by clicking on the button in any product. (this was done using the true/false state and the engine that changed the value of the state, and with it changed the style of all components).
I roughly understand that these issues can be resolved with the help of props or change of architecture, but I decided not to waste another few days in search of answers, but to ask for help

Thank you very much for listening to me, I hope for your help :)
March 19th 20 at 08:56
1 answer
March 19th 20 at 08:58
Solution
1. What's with the names? NewsItem, setItem, result, clickFilter, styles, buy - never write like that even in jest. Replace: NewsItem on a Product(or ShopItem), setItem - all, remove, result on products, clickFilter on handleAddToCartClick, styles in className, in buy cart.

2. There is no sense to pass ShopItem each property item separately. Only complicate the analysis of your code. Better:
{products.map(product => (
<ShopItem
key={product.id}
className={'item'}
item={product}
onAddToCartClick={this.handleAddToCartClick}
/>
)}


3. Base path and base path that should not contain a particular endpoint. Correct:
const BASE_PATH = 'https://api.punkapi.com/v2';

/* ... */

fetch(`${BASE_PATH}/beers`)


How to add received "goods" in the basket? I couldn't use the values of the state.result for subsequent adding of state.basket.
the result is just an array of objects. It is possible to access any product by using this.state.result[indexobject], but nothing with this data directly to do not I like using setState

If you don't understand how to work with data(arrays, objects), you should now focus our attention on the study of this question:
JavaScript: data Structures
You there is no sense to copy the item in the cart array, you can only add item id and quantity:
class Store extends Component {
 state = {
 products: [],
cart:[],
};

 handleAddToCartClick = (id, quantity) => {
 const { cart } = this.state;
 const itemIndex = cart.findIndex(item => item.id === id);

 if (itemIndex !== -1) {
 const newCart = [cart...];
 newCart[itemIndex] = { id, quantity: cart[itemIndex].quantity + quantity };
 this.setState({ cart: newCart });
 } else {
 this.setState(prevState => ({
 cart: [
...prevState.cart
 { id, quantity },
],
}));
}
 };

const ShopItem = ({ className, item, onAddToCartClick }) => (
the <div>
 {/* ... */}
 <button onClick={() => onAddToCartClick(item.id, 1)}>add to cart</button>
<div/>
);

The question stems from 1st, and whether it is normal practice to add to state data received from the API? If not, then where can they be stored?

In redux store. redux should use here though, because the same data about the products you will need and in the basket, on the checkout page.

I wanted to create each "item" button, which will change the style of this particular product (it does not carry any meaning, but I wanted to implement it to understand some things).
My component has NewsItem props styles, which sets the style to the component.

The easiest option is to use a hook useState:
import React { useState } from 'react';

const ShopItem = ({ className, item, onAddToCartClick } ) => {
 const [isActive, setIsActive] = useState(false);

 handleToggleActiveClick = () => {
setIsActive(!isActive);
};

 return (
the <div>
 <ul className={`${className}${isActive ? 'active' : "}`}>
 {/* ... */} 
 <button onClick={handleToggleActiveClick}>Toggle active</button>
</ul>
<div/>
);
}
Thank you very much!!!
The code suffers, Yes, I will try to work in the right direction.
If the index is there anything else I could understand, with Huck useState definitely not
To be able to afford such a solution, it would take a lot of time - Anabelle_Barton commented on March 19th 20 at 09:01

Find more questions by tags ReactJavaScript