I have a view with the list of articles the user add to basket.
In each article i have an increment/decrement button to edit the quantity. The increment/decrement buttons are working because it's adding in my array a new Object every time my user change the quantity
For now, i just have a " " and "-" button, but i would like to see the number of the quantity
What i was thinking about :
- get all the articles list and count the duplicate in a useEffect (every time the articles list is changing)
- set the article id and quantity with useState object
What is the best way to count individual quantity of each articles ?
here my component with the articles map and increment/decrement buttons
import React from 'react';
import { Table } from 'react-bootstrap';
import { useFieldArray } from 'react-hook-form';
export const ListArticle = ({ watch, control }) => {
const list = watch('Articles');
//listWithoutDuplicates is because i just want to see once my articles even if the quantity is more than 1
const listWithoutDuplicates = list?.filter(
(ele, ind) => ind === list?.findIndex((elem) => elem.name === ele.name)
);
const { append, remove } = useFieldArray({
control,
name: 'Articles',
});
const increment = (oneArticle) => {
append(oneArticle);
};
const decrement = (oneArticle) => {
remove(oneArticle);
};
return (
<>
<Table responsive>
<thead>
<tr>
<th> Name </th>
<th> Color</th>
<th> Quantity </th>
</tr>
</thead>
<tbody>
{listWithoutDuplicates?.map((oneArticle, index) => {
return (
<tr key={index}>
<td>
<span>{oneArticle?.name}</span>
</td>
<td>
<span>{oneArticle?.color}</span>
</td>
<td>
<button type="button" onClick={() => decrement(oneArticle)}>
-
</button>
<p> HERE MY QUANTITY </p>
<button type="button" onClick={() => increment(oneArticle)}>
</button>
</td>
</tr>
);
})}
</tbody>
</Table>
</>
);
};
CodePudding user response:
Why you just don't hold the quantity field for each article instead of storing multiple articles ?
const { append, remove, update } = useFieldArray({
control,
name: 'Articles',
});
const increment = (index) => {
const oneArticle = {...list[index]};
oneArticle.quantity = 1;
update(index, oneArticle);
};
const decrement = (index) => {
const oneArticle = {...list[index]};
// It's the last quantity of the article so we should remove it from the list.
if(oneArticle.quantity === 1) {
remove(index);
// It's not the last quantity of the article so we should decrease the quantity.
} else {
oneArticle.quantity -= 1;
update(index, oneArticle);
}
};
And then just loop through the list data and there is no need to use listWithoutDuplicates anymore.
<tbody>
{list?.map((oneArticle, index) => {
return (
<tr key={index}>
<td>
<span>{oneArticle?.name}</span>
</td>
<td>
<span>{oneArticle?.color}</span>
</td>
<td>
<span>{oneArticle?.quantity}</span>
</td>
<td>
<button type="button" onClick={() => decrement(index)}>
-
</button>
<button type="button" onClick={() => increment(index)}>
</button>
</td>
</tr>
)
})}
</tbody>
And another point is that remove gets index or array of indexes not the object.
CodePudding user response:
use Like this...
import React,{useState} from 'react';
import { Table } from 'react-bootstrap';
import { useFieldArray } from 'react-hook-form';
export const ListArticle = ({ watch, control }) => {
const [list, setList] = useState(watch('Articles'));
//listWithoutDuplicates is because i just want to see once my articles even if the quantity is more than 1
//const listWithoutDuplicates = list?.filter(
// (ele, ind) => ind === list?.findIndex((elem) => elem.name === ele.name)
// );
const { append, remove } = useFieldArray({
control,
name: 'Articles',
});
const increment = (index) => {
//append(oneArticle);
let newList =list;
newList[index].quantity =(newList[index].quantity || 0) 1
setList(newList)
};
const decrement = (index) => {
//remove(oneArticle);
let newList =list;
newList[index].quantity =(newList[index].quantity || 0) -1
setList(newList)
};
return (
<>
<Table responsive>
<thead>
<tr>
<th> Name </th>
<th> Color</th>
<th> Quantity </th>
</tr>
</thead>
<tbody>
{list?.map((oneArticle, index) => {
return (
<tr key={index}>
<td>
<span>{oneArticle?.name}</span>
</td>
<td>
<span>{oneArticle?.color}</span>
</td>
<td>
<button type="button" onClick={() => decrement(index)}>
-
</button>
<p>{oneArticle.quantity || 0}</p>
<button type="button" onClick={() => increment(index)}>
</button>
</td>
</tr>
);
})}
</tbody>
</Table>
</>
);
};
I hope this will help you!