es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

React.useMemo está volviendo a renderizar todos los elementos del arreglo.

Tengo un componente de React que almacena un conjunto de frutas en useState. Tengo una función memorizada (visibleFruits) que filtra las frutas. Mapeo visibleFruits al DOM.

El problema es que cuando marco una fruta, todas las frutas visibles se vuelven a renderizar.

Esperaba que solo se volviera a renderizar la seleccionada, ya que es la única que está cambiando.

¿Existe alguna forma de utilizar este patrón pero evitar que todo se vuelva a renderizar al marcar?

En la vida real, hay una función compleja en useMemo de visibleFruits. Por lo tanto, no puedo simplemente agregar el filtro antes del mapeo.

Edit, aquí está la edición actualizada:

“`import React from ‘react’

const Example = () => {
const [fruits, setFruits] = React.useState([
{ id: 1, name: 'apple', visible: true, selected: false },
{ id: 2, name: 'banana', visible: false, selected: false },
{ id: 3, name: 'orange', visible: true, selected: false }
])

const visibleFruits = React.useMemo(() => {
return fruits.filter((f) => f.visible)
}, [fruits])

const handleCheck = (bool, id) => {
setFruits((prev) => {
return prev.map((f) => {
if (f.id === id) {
f.selected = bool
}
return f
})
})
}

return (
<div>
{visibleFruits.map((fruit) => {
return <fruitoption fruit="{fruit}" handlecheck="{handleCheck}"></fruitoption>
})}
</div>
)
}

const FruitOption = ({ fruit, handleCheck }) => {
console.log('<em>* THIS RENDERS TWICE EVERY TIME USER SELECTS A FRUIT *</em>')
return (
<div key="{fruit.id}">
<input checked="{fruit.selected}" onchange="{(e)" ==""> handleCheck(e.target.checked, fruit.id)}
type='checkbox'
/>
<label>{fruit.name}</label>
</div>
)
}

export default Example
“`

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    El problema con todos los frutos visibles que se vuelven a renderizar cuando se marca un solo fruto se debe al hecho de que todos los frutos son parte del mismo objeto de estado. Cuando se actualiza un solo fruto, se actualiza todo el arreglo de frutos, lo que hace que se vuelvan a renderizar todos los frutos visibles.

    Para evitar esto, una opción sería desglosar el estado de cada fruto en su propio componente. De esta manera, cada componente de fruto solo se actualizaría cuando su propio estado cambie, en lugar de todo el arreglo de frutos.

    Otra opción sería utilizar el gancho useCallback con la función handleCheck para memoizarla, de manera que solo cambie cuando sea necesario. Esto puede ayudar a evitar renderizaciones innecesarias.

    Además, en lugar de modificar el objeto existente, se recomienda crear un nuevo objeto con los valores actualizados, para evitar comportamientos inesperados debido a un estado mutable.

Comments are closed.