Así que tengo este componente llamado contadores donde el estado se ve así
state = { counters: [ { id: 1, value: 0 }, { id: 2, value: 3 }, { id: 3, value: 0 }, { id: 4, value: 0 }, ], };Y estoy tratando de incrementar el valor cada vez que se hace clic en un botón correspondiente. Esta es la función que escribí para él.
handleIncrement = (counter) => { const counters = [...this.state.counters]; const index = counters.indexOf(counter); counters[index] = { ...counter }; counters[index].value++; this.setState({ counters }); };no funciona Y he aquí algunas observaciones adicionales.
por lo que parece, el problema parece estar en la línea
const index = counters.indexOf(counter);Como el valor del índice siempre se devuelve como -1.
intente esto para obtener el índice:
const index = counters.findIndex(x => x.id === counter.id);Puede usar el índice para actualizar el registro correspondiente en la matriz.
const idx = this.state.counters.findIndex((counter) => counter.id === id);Implementación completa: -
import React from "react"; import "./styles.css"; export default class App extends React.Component { constructor(props) { super(props); this.state = { counters: [ { id: 1, value: 0 }, { id: 2, value: 3 }, { id: 3, value: 0 }, { id: 4, value: 0 } ] }; } handleClick = (id) => { const idx = this.state.counters.findIndex((counter) => counter.id === id); const counters = [...this.state.counters]; counters[idx] = { ...counters[idx], value: counters[idx].value++ }; this.setState(counters); }; render() { return ( <div> {this.state.counters.map((counter) => ( <div> <button onClick={() => this.handleClick(counter.id)}> Button {counter.id} </button> <span>Value {counter.value}</span> <hr /> </div> ))} </div> ); } }Codesandbox - https://codesandbox.io/s/musing-black-cipbbs?file=/src/App.js
Agrego mi respuesta aquí en caso de que otra alma confundida tropiece con ella.
Aunque parecía que el problema estaba dentro de la línea
const index = counters.indexOf(counter);En realidad, estaba en el componente secundario donde se invocaba la función. Dentro del parámetro estaba pasando counters.value mientras que la función handleincrement dentro del componente principal no esperaba el valor, sino el objeto completo.
El código en su condición de trabajo es el siguiente Componente principal:
import React, { Component } from "react"; import Counter from "./counter"; class Counters extends Component { state = { counters: [ { id: 1, value: 0 }, { id: 2, value: 3 }, { id: 3, value: 0 }, { id: 4, value: 0 }, ], }; handleIncrement = (counter) => { const counters = [...this.state.counters]; const index = counters.indexOf(counter); console.log(index); counters[index] = { ...counter }; counters[index].value++; this.setState({ counters }); };Componente hijo:
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> import React, { Component } from "react"; class Counter extends Component { render() { return ( <button onClick={() => this.props.onIncrement(this.props.counter)} className="btn btn-secondary btn-sm" > Increment </button> ) } ]