Todavía estoy aprendiendo React , así que sea comprensivo.
En un componente he declarado una lista de elementos. Desde un componente principal cuando se agrega un nuevo elemento, paso ese elemento a través de prop. El problema es que me gustaría actualizar una lista solo cuando aparece un nuevo elemento. Tengo un código como ese:
export default function Expenses(props) { const [expenses, setExpenses] = useState(INITIAL_EXPENSES); const [filteredYear, setFilteredYear] = useState('2020'); const filterExpenses = (date) => { setFilteredYear(date); } if (props.newExpense.hasOwnProperty('expenseTitle')) { setExpenses((prev) => { const newExpenses = [...prev] newExpenses.push(props.newExpense); props.newExpense = null; return newExpenses; }) } const filteredExpenses = expenses.filter(exp => exp.expenseDate.getFullYear().toString() === filteredYear); return ( <Card className="expenses"> <ExpensesFilter year={filteredYear} onExpensesFilter={filterExpenses}/> <ExpenseChart expenses={filteredExpenses}/> <ExpensesList items={filteredExpenses}/> </Card> )}
supongo que if
if (props.newExpense.hasOwnProperty('expenseTitle')) { no está bien hecho porque de alguna manera props.newExpense debe borrarse después de agregarse a la lista newExpenses. Pero no se como hacerlo?
El segundo problema que tengo es un error Too many re-renders. React limits the number of renders to prevent an infinite loop. que en esa forma de código está completamente bien porque después de agregar un nuevo elemento a la lista dentro de props.newExpense todavía existe ese elemento, por lo que si una y otra vez es cierto.
No cambie la forma en que declaré la clase/función de Expenses . Ese no es el punto de este problema.
Entonces, el problema con su código es básicamente que está configurando el estado en cada renderizado, y cuando configura el estado en un nuevo valor, desencadena otro renderizado, que a su vez establece el estado y ... obtiene la esencia.
Ingrese el gancho useEffect . useEffect le permite definir los efectos secundarios de los cambios en un estado o accesorios particulares.
Lo que quiere hacer aquí es hacer algo solo cuando cambie el accesorio newExpense , por lo que tendría que hacer algo así: (Tenga en cuenta que necesita importar useEffect from react )
useEffect(() => { if (props.newExpense.hasOwnProperty('expenseTitle')) { setExpenses((prev) => { const newExpenses = [...prev] newExpenses.push(props.newExpense); props.newExpense = null; return newExpenses; }) }, [props.newExpense]) El segundo argumento para useEffect es una matriz de dependencia, lo que significa que si una de las cosas en la matriz cambia, ejecute la función de efecto.
Tenga en cuenta que rara vez es bueno establecer el estado en useEffect , por lo que sugiero refactorizar el mecanismo si puede