Estoy buscando una referencia canónica de cómo se ha tratado esto.
Si tengo un componente que se ve así:
const MyComponent = ({ value = [] }) => { const [otherValue, setOtherValue] = React.useState([]); React.useEffect(() => { setOtherValue(value); }, [value]); return <div> doesn't matter</div> };
Lo que sucede es:
value
cambia, se dispara la devolución de llamada useEffect, y esto llama a setStatevalue
es nulo, entonces se asigna la matriz predeterminada, y este es un objeto nuevo , y esto a su vez provoca una nueva representación.La solución puede ser declarar su accesorio predeterminado como una constante, como:
const DEFAULT_VALUE = []; const MyComponent = ({ value = DEFAULT_VALUE }) => { const [otherValue, setOtherValue] = React.useState([]);
Mis preguntas:
Para cada una de las versiones 16, 17, 18 de React:
Puede usar una propiedad llamada defaultProps. Con defaultProps, el valor predeterminado de su propiedad se convierte en parte de la definición del componente y ya no se restablece en cada procesamiento, lo que evita el bucle infinito con useEffect. Entonces será algo así:
const MyComponent = ({ value }) => { const [otherValue, setOtherValue] = React.useState([]); React.useEffect(() => { setOtherValue(value); }, [value]); return <div> doesn't matter</div> }; MyComponent.defaultProps = { value: [] };
Y sí, hay una regla de pelusa para eso, pero la regla es:
Hacer cumplir una definición de accesorios predeterminados para cada accesorio que no sea un accesorio requerido
Así que no es exactamente lo que quieres porque funciona con reglas de tipo prop, pero creo que te ayudará con eso. Si desea ver más detalles sobre esta regla, aquí está el archivo Léame que la describe.
El bucle infinito no está relacionado con ReactJS
, por lo que ninguna versión pudo solucionarlo. el problema vuelve a los valores primitive/reference
.
Cuando estás usando esto:
const MyComponent = ({ value = [] }) => { const [otherValue, setOtherValue] = React.useState([]); React.useEffect(() => { setOtherValue(value); }, [value]);
Incluso para un cambio de accesorios, si el siguiente value
es un javascript undefined
, cree un nuevo valor []
y asígnelo al value
y React.useEffect
cree que es nuevo (en realidad, este pensamiento es correcto) e intenta obtener el nuevo accesorio y compararlo con el último y para cualquiera de estas acciones usa value
y cada vez es nuevo porque su referencia es nueva.
Pero su solución es asombrosa, para cualquier valor de reference type
debemos almacenarlo en caché y luego usarlo para evitar crearlo una y otra vez:
const DEFAULT_VALUE = []; const MyComponent = ({ value = DEFAULT_VALUE }) => {
ESLint :
Hay algunas reglas de complementos para obligar a los desarrolladores a agregar valores predeterminados en accesorios requeridos o no requeridos, pero ninguno de ellos le sugiere que almacene en caché los valores de tipo de referencia para los accesorios predeterminados.