Why mapped items states are affecting on each other in React? - reactjs

I mapped an array of products, each of them have, I am managing state with redux, each mapped item has quantity if I increase quantity, price should also increase, so when I am changing quantity of one item second array price also changes based on previous item quantity, so why are different items affecting on each other? here is the code:
const handleProductQuantity = (event) => {
dispatch(setProductQuantity(event.target.value));
}
<div className='cart'>
<div className='products-in-cart-wrapper'>
{ productsInCart ? (
productsInCart.map(productInCart => (
<div className='product-in-cart'>
<div className="product-in-cart-name">
<div className="label label-title">
Title:
</div>
<div className="value value-title">
{productInCart.title}
</div>
</div>
<div className="product-in-cart-price">
<div className="label label-price">
Price:
</div>
<div className="value value-price">
{productQuantity * productInCart.price}
</div>
</div>
<div className="product-in-cart-price">
<div className="label label-price">
Quantity:
</div>
<div className="value value-quantity">
<input onChange={handleProductQuantity} type="number" placeholder='1'/>
</div>
</div>
<div className="button-cont">
<button className="buy-button" onClick={test}>
Buy now
</button>
</div>
</div>
))
) : (
<div> Loading... </div>
)
}
<div className="total-price-button-cont">
<button>Buy all for: 100$</button>
</div>
</div>
</div>

You should always use a key prop on items inside array. if you have an id by example, this would look like that :
<div className="product-in-cart" key={productInCart.id}>...</div>
React uses key to properly identify items inside the array. You problem might be different tho but you should always uses key
edit: productQuantity should be productInCart.productQuantity ;)

Related

How can I click on a button on the same element with a specific name?

This is ant-react project.
html:
<div class="list">
<div class="item">
<div>
<div>
<div class="head">
<span>name 1</span>
</div>
<div class="body">
<div>
<button>done</button>
</div>
</div>
</div>
</div>
</div>
<div class="item">
<div>
<div>
<div class="head">
<span>name 2</span>
</div>
<div class="body">
<div>
<button>done</button>
</div>
</div>
</div>
</div>
</div>
js:
cy.get(`div:contains('name1')`)
.should('be.visible')
.invoke('show')
.should('be.visible')
.find('button:contains("Done")').eq(0).click({ multiple: true })
There are a lot of item elements. I need to click on the 'Done' button of the element with name "name 1".
But every time i get error:
Timed out retrying after 4050ms: cy.click() failed because this element is detached from the DOM.
...
Cypress requires elements be attached in the DOM to interact with them.
How can I do it?
You can do something like this. The first parent will go to <div class="head"> and the next parent will move to div just above. Now using within we will make sure that the Done button is clicked for name 1.
cy.contains('span', 'name1')
.parent()
.parent()
.within(() => {
cy.contains('button', 'done').click()
})

Problems with the UseState hook typing

I'm trying to put useState hook values to a component via props.
As I understand typescript complains that I didn't specify setActive to boolean type. Am I right? If so, how can I do it?
const Card = () => {
const [activeModal, setActiveModal] = useState<boolean>(false)
return (
<>
<ApproveModal active={activeModal} setActive={setActiveModal} />
<div className="card">
<div className="card-wrapper">
<div className="card-header">
<div className="card-header-left">
<img src={token} alt="token" />
<div className="card-header-info-tag">
<h1>WETH-WBNB LP</h1>
<p>Auto-Compounding</p>
</div>
</div>
<div className="card-header-right">
<p>Pancake</p>
<img src={pancake} alt="pancake" />
</div>
</div>
<div className="card-info">
<div className="card-info-item">
<div className="card-info-item-title">Staked</div>
<div className="card-info-item-value">$482.22K</div>
<div className="card-info-item-description">39595 LPs</div>
</div>
<div className="card-info-item">
<div className="card-info-item-title">APY</div>
<div className="card-info-item-value">365%</div>
<div className="card-info-item-description">Daily: 2.00%</div>
</div>
<div className="card-info-item">
<div className="card-info-item-title">TVL</div>
<div className="card-info-item-value">$482.22K</div>
<div className="card-info-item-description">39595 LPs</div>
</div>
</div>
<div className="card-button" onClick={() => setActiveModal(!activeModal)}>Approve</div>
</div>
</div>
</>
)
}
"text to fix little text problem"
"text to fix little text problem"
"text to fix little text problem"
And ApproveModal
interface ApproveModalProps {
active: boolean;
setActive: boolean;
}
const ApproveModal = ({active, setActive}: ApproveModalProps) => {
return (
<div className="modal">
<div className="modal-content">
<div className="modal-header">
<img src={modalLogo} alt="modalLogo" />
<div className="modal-header-info">
<div className="modal-header-info-title">WETH-WBNB LP</div>
<div className="modal-header-info-description">Auto-Compounding</div>
</div>
<div className="modal-header-info-swap">#PancakeSwap</div>
<img src={closeIcon} alt="closeIcon" className="close-button" />
</div>
<div className="modal-actions">
<div className="modal-actions-buttons">
<div className="deposit">Deposit</div>
<div className="withdrow">Withdrow</div>
</div>
</div>
<div className="modal-balance">
<div className="modal-balance-header">
<div className="modal-balance-header-left">
<div className="balance">Balance</div>
<div className="link">Create LP</div>
</div>
<div className="modal-balance-header-right">
<img src={updateIcon} alt="updateIcon" />
<div className="value">0.0000</div>
<div className="value-description">($0.00)</div>
</div>
</div>
<div className="balance-input">
<input type="text" />
<div className="input-button">MAX</div>
</div>
</div>
<div className="modal-info">
<div className="modal-info-apy">
<div className="modal-info-apy-title">APY</div>
<div className="modal-info-item">
<div className="apy-value">365%</div>
<div className="apr-value">APR: Swap 70.9% + GROW 73.5%</div>
</div>
</div>
<div className="modal-info-contact">
<div className="modal-info-contact-title">Contact</div>
<div className="modal-info-item">
<div className="contact-link">View on BScScan</div>
<div className="contact-address">oxAD6bD158869a97219447cf63b090</div>
</div>
</div>
<div className="modal-button">Approve</div>
<h1>No deposit free. No withdraw free.</h1>
</div>
</div>
</div>
)
}
Here is the code
The problem lies in your Card component. The error is saying that the setActive prop expects to receive a boolean value, but you are providing it with a function.
It should be expecting a function. You’ll want to change the props types on your Card such that setActive is a function whose argument is a boolean.
interface CardProps {
setActive: (active: boolean) => void;
…
If you want to be able to use a prevState callback when calling setActive inside the Card component, then you can use the exact type of your setActiveModal function, which is this:
interface CardProps {
setActive: React.Dispatch<React.SetStateAction<boolean>>;
…

React grid layout not working with firebase

I changed my code so that it would bring in the information from cloud firestore instead of hardcoding it. This is my old code without firebase:
<div className="grid">
<div className="grid-child">
<img className="subImg" src={amsterdam}></img>
<p className="subImgTitle">Amsterdam</p>
<p className="subImgText">Hotels from £?</p>
</div>
<div className="grid-child">
<img className="subImg" src={london}></img>
<p className="subImgTitle">London</p>
<p className="subImgText">Hotels from £?</p>
</div>
<div className="grid-child">
<img className="subImg" src={madrid}></img>
<p className="subImgTitle">Madrid</p>
<p className="subImgText">Hotels from £?</p>
</div>
<div className="grid-child">
<img className="subImg" src={paris}></img>
<p className="subImgTitle">Paris</p>
<p className="subImgText">Hotels from £?</p>
</div>
</div>
And this is my new code with firebase:
destinations?.map(destination => {
return (
<div className="grid">
<div className="grid-child">
<img className="subImg" src={destination.img}></img>
<p className="subImgTitle">{destination.title}</p>
<p className="subImgText">Hotels from £{destination.price}</p>
</div>
</div>
)
})
In the original code, the images are all in a row however now they are all in one column. I am not too sure how to fix this so any help would be greatly appreciated. Thanks :)
If you compare the DOM rendered by each example, you will see that the problem is that in the first example you have a single <div className="grid"> but in the second you wrap each image in <div className="grid">. To fix this, just be sure to create only one grid:
<div className="grid">
{ destinations?.map(destination => {
return (
<div className="grid-child">
<img className="subImg" src={destination.img}></img>
<p className="subImgTitle">{destination.title}</p>
<p className="subImgText">Hotels from £{destination.price}</p>
</div>
)
})
}
</div>
As a next step, consider refactoring a GridChild component that encapsulates the HTML for each image in the grid.

All child elements inheriting onclick event from parent div on React

This is my code on return section. All children elements is ineriting click events and when I click it is giving me the object of that child element not parent.
return (
<div className={css(style.cell)} onClick={this.props.onClickHandle}>
<div className={css(style.image)}>
<CircleImage size={50} url = {"http://www.ruralagriventures.com/wp-content/uploads/2017/05/man-team.jpg"}/>
</div>
<div className={css(style.info)}>
<div className={css(style.profile)}>
<span>{this.props.name}</span>
<span className={css(style.lastMessage)}>Latest Message</span>
</div>
<div className={css(style.detail)}>
<span>a few seconds ago</span>
<span className={css(style.counter)}>5</span>
</div>
</div>
</div>
)
I only want an object from parent div, not children. Before passing props
I assigned this.onClickHandle = this.onClickHandle.bind(this);
You can use refs, refer this link
onClickHandle(e){
this.parentDiv //parent object
}
return (
<div ref={(parentDiv) => { this.parentDiv = parentDiv; }} className={css(style.cell)} onClick={this.props.onClickHandle}>
<div className={css(style.image)}>
<CircleImage size={50} url = {"http://www.ruralagriventures.com/wp-content/uploads/2017/05/man-team.jpg"}/>
</div>
<div className={css(style.info)}>
<div className={css(style.profile)}>
<span>{this.props.name}</span>
<span className={css(style.lastMessage)}>Latest Message</span>
</div>
<div className={css(style.detail)}>
<span>a few seconds ago</span>
<span className={css(style.counter)}>5</span>
</div>
</div>
</div>
)

Value empty in react UI but visible in the console

I was using react with flux. When I checked in the console, values are coming but when I check in React developer tools, expected value is empty. If I am sending a single object then it is working fine. But if an array is sent, then nothing is displayed.
Can anybody please tell what is the problem? The code and image of the same is as below.
Code:
var Product = React.createClass({
render: function(){
var product = this.props.product;
return (<div className="col-md-8"><hr/>
{product.map(function(items){
console.log(" Items in the field :"+JSON.stringify(items));
<div className="col-sm-6">
<div className="col-sm-4">
<img src={"/src/image/"+ items.image}/>
</div>
<div className="col-sm-2">
<h2> {items.name} </h2>
<p> {items.description} </p>
<h3> Price: ${items.price} </h3>
<h4>Inventory: {items.inventory}</h4>
</div>
</div>
})}
</div>
)
}
});
You need to return from function call
var Product = React.createClass({
render: function(){
var product = this.props.product;
return (<div className="col-md-8"><hr/>
{product.map(function(items){
console.log(" Items in the field :"+JSON.stringify(items));
return (<div className="col-sm-6">
<div className="col-sm-4">
<img src={"/src/image/"+ items.image}/>
</div>
<div className="col-sm-2">
<h2> {items.name} </h2>
<p> {items.description} </p>
<h3> Price: ${items.price} </h3>
<h4>Inventory: {items.inventory}</h4>
</div>
</div>);
})}
</div>
)
}
});

Resources