Initialement ce que j'essaie de faire est d'attacher l'événement deleteItem à chaque article de livre. J'ai une action 'DELETE_BOOK' qui accepte l'identifiant de l'objet du livre, puis dans les réducteurs, il renvoie la liste de livres sans l'élément de livre que j'ai spécifié pour être supprimé. L'élément est supprimé, mais pour une raison quelconque, il ajoute l'ancienne liste (6 éléments) sur la nouvelle liste (5 éléments après la suppression) et maintenant je me retrouve avec 11 éléments.React/Redux - Je supprime un élément sur un total de 6, quand le rendu se produit il ajoute l'ancienne liste (6) à la nouvelle liste (5) maintenant j'ai 11 éléments?
//book-list.js
"use strict"
import React from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import {getBooks, deleteBook} from '../../actions/booksActions';
import BookItem from './book-item';
import BookForm from './book-form';
import Cart from './cart';
class BookList extends React.Component {
constructor(props){
super(props);
this.deleteBookItem = this.deleteBookItem.bind(this);
}
componentDidMount(){
this.props.getBooks();
}
deleteBookItem(_id){
this.props.deleteBook(_id);
}
render(){
const bookList = this.props.books.map(function(book){
return (
<BookItem
key={book._id}
_id={book._id}
title={book.title}
description={book.description}
price={book.price}
deleteBookItem={this.deleteBookItem}
/>
)
}, this);
return(
<div>
<div className="page-header">
<h1 className="text-center">The React BookStore</h1>
</div>
{ this.props.msg &&
<div className="alert alert-info text-center"
role="alert">{this.props.msg}</div>
}
<Cart />
<div className="row">
<div className="col-xs-12 col-sm-8">
<div className="row">
{bookList}
</div>
</div>
<div className="col-xs-12 col-sm-4">
<BookForm />
</div>
</div>
</div>
)
}
}
//just return the data from the store
function mapStateToProps(state){
return {
books: state.books.books,
msg: state.books.msg
}
}
function mapDispatchToProps(dispatch){
return bindActionCreators({
getBooks: getBooks,
deleteBook: deleteBook
}
, dispatch);
}
//connects component to the store
export default connect(mapStateToProps, mapDispatchToProps)(BookList);
----------------------------------------------------------------------------
//book-item.js
import React from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import {addToCart, updateCart} from '../../actions/cartActions';
class BookItem extends React.Component{
constructor(props){
super(props);
this.deleteBookItem = this.deleteBookItem.bind(this);
}
deleteBookItem(){
const index = this.props._id;
this.props.deleteBookItem(index);
}
handleCart =() => {
const book = [...this.props.cart, {
_id: this.props._id,
title: this.props.title,
description: this.props.description,
price: this.props.price,
qty: 1
}];
if(this.props.cart.length > 0){
let _id = this.props._id;
let cartIndex = this.props.cart.findIndex(function(cart){
return cart._id === _id;
});
if(cartIndex === -1){
this.props.addToCart(book);
}
else{
this.props.updateCart(_id, 1);
}
}
else {
this.props.addToCart(book);
}
}
render(){
return(
<div className="col-xs-12 col-md-6" key={this.props._id}>
<div className="well">
<h2 className="text-center">{this.props.title}</h2>
<h2 className="text-center">{this.props.description}
</h2>
<h2 className="text-center">{this.props.price}</h2>
<button className="btn btn-success btn-block" onClick=
{this.handleCart}>
<i className="glyphicon glyphicon-shopping-cart">
</i>
<span> Add To Cart</span>
</button>
<button className="btn btn-danger btn-block" onClick=
{this.deleteBookItem}>
<i className="glyphicon glyphicon-trash"></i>
<span> Delete Book</span>
</button>
</div>
</div>
)
}
}
function mapStateToProps(state){
return {
cart: state.cart.cart
}
}
function mapDispatchToProps(dispatch){
return bindActionCreators(
{
addToCart: addToCart,
updateCart: updateCart,
}
, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(BookItem);
---------------------------------------------------------------------------
//bookActions.js
"use strict"
export function getBooks(){
return {
type: 'GET_BOOKS'
}
}
export function postBook(book){
return {
type: 'POST_BOOK',
payload: book
}
}
export function deleteBook(_id){
return {
type: 'DELETE_BOOK',
payload: _id
}
}
export function updateBook(book){
return {
type: 'UPDATE_BOOK',
payload: book
}
}
---------------------------------------------------------------------------
//booksReducers.js
"use strict"
//BOOKS REDUCERS
let defaultBooks = [
{
_id: 1,
title: 'Book 1',
description: 'Book 1 Description',
price: 19.99
},
{
_id: 2,
title: 'Book 2',
description: 'Book 2 Description',
price: 29.99
},
{
_id: 3,
title: 'Book 3',
description: 'Book 3 Description',
price: 39.99
},
{
_id: 4,
title: 'Book 4',
description: 'Book 4 Description',
price: 49.99
},
{
_id: 5,
title: 'Book 5',
description: 'Book 5 Description',
price: 59.99
},
{
_id: 6,
title: 'Book 6',
description: 'Book 6 Description',
price: 69.99
}
];
export function booksReducers(state = { books: defaultBooks }, action){
switch(action.type){
case "GET_BOOKS":
return {...state, books:[...state.books]}
break;
case "POST_BOOK":
return {...state, books:[...state.books, ...action.payload],
msg:'Saved! Click to continue', style:'success',
validation:'success'}
break;
case "POST_BOOK_REJECTED":
return {...state, msg:'Please, try again', style:'danger',
validation:'error'}
break;
case "RESET_BUTTON":
return {...state, msg:null, style:'primary', validation:null}
break;
case "DELETE_BOOK":
// Create a copy of the current array of books
const currentBookToDelete = [...state.books];
// Determine at which index in books array is the book to be deleted
const indexToDelete = currentBookToDelete.findIndex(function(book){
return book._id === action.payload._id;
});
//use slice to remove the book at the specified index
return {books: [...currentBookToDelete.slice(0, indexToDelete),
...currentBookToDelete.slice(indexToDelete + 1)]}
break;
case "UPDATE_BOOK":
// Create a copy of the current array of books
const currentBookToUpdate = [...state.books]
// Determine at which index in books array is the book to be deleted
const indexToUpdate = currentBookToUpdate.findIndex(
function(book){
return book._id === action.payload._id;
}
)
// Create a new book object with the new values and with the same
array index of the item we want to replace. To achieve this we will
use ...spread but we could use concat methos too
const newBookToUpdate = {
...currentBookToUpdate[indexToUpdate],
title: action.payload.title
}
// Log has the purpose to show you how newBookToUpdate looks like
console.log("what is it newBookToUpdate", newBookToUpdate);
//use slice to remove the book at the specified index, replace with
the new object and concatenate witht he rest of items in the array
return {
books: [...currentBookToUpdate.slice(0, indexToUpdate),
newBookToUpdate, ...currentBookToUpdate.slice(indexToUpdate + 1)]
}
break;
default:
break;
}
return state
}
[enter code here][1]
[1]: https://i.stack.imgur.com/JCTyr.png
Oui Je suivais un tutoriel d'où venait ce code bookReducer et c'est pourquoi j'utilisais findIndex. Mais j'essaie de m'éloigner un peu du tutoriel parce que le tutoriel les supprimait en utilisant une liste déroulante et une soumission, mais je voulais attacher la fonctionnalité de suppression directement au niveau du bouton. Mais laissez-moi votre chemin à la place. –
Pourriez-vous publier le lien vers le tutoriel s'il vous plaît? –
[Pleine pile Universal React avec Redux, Node js et MongoDB] (https://www.udemy.com/full-stack-universal-react-with-redux-express-and-mongodb/?src=sac&kw=full) –