Buscando un enfoque que me permita usar ganchos de estado en listas dinámicas de componentes funcionales. Tal como está mi código, una nueva representación de la lista da errores relacionados con el cambio de números de ganchos.
Tengo un componente maestro que representa una lista de componentes funcionales, la longitud de la lista depende del estado que tenga el maestro, y ese estado puede actualizarse mediante un gancho de efecto; el cambio ocurre de forma asíncrona. Quiero permitir que los elementos de la lista tengan cada uno su propio estado: el estado controla algunos efectos visuales.
Cuando cambia el tamaño de mi lista, recibo errores de este tipo:
react-dom.development.js:86 Advertencia: React ha detectado un cambio en el orden de los Hooks llamados por EstateOverview. Esto dará lugar a errores y errores si no se soluciona. Para obtener más información, lea las Reglas de Hooks: https://reactjs.org/link/rules-of-hooks
Renderizado anterior Renderizado siguiente
- estado de uso estado de uso
- estado de uso indefinido
y
Error no detectado: se renderizaron más ganchos que durante el renderizado anterior.
El código:
la lista, mostrando las propiedades inmobiliarias como una lista de PropertyGroup
import React from 'react'; import List from '@mui/material/List'; import PropertyGroup from "./PropertyGroup.js"; export default function EstateOverview(props) { return ( <List> {props.estateOverview.propertyGroups.map((group) => PropertyGroup(group))} </List> ); }el elemento de la lista, esto está mucho más simplificado, lo suficiente como para reproducir el problema
import React from 'react'; export default function PropertyGroup(props) { // trivial state, sufficient to cause error // if I remove this state the demo runs without error // but in my real code I have meaningful state to maintain const [x, setX] = React.useState(false); return ( <h2 key={props.name}>{props.name}</h2> ); }Lo anterior se invoca desde este componente maestro Inmobiliario
import React, { useEffect, useState } from 'react'; import EstateOverview from "./EstateOverview.js"; export default function Estate(props) { const [estateOverview, setEstateOverview] = useState( { "propertyGroups" : [ { name: "The Close"} ] } ); useEffect(() => { const newEstateOverview = { propertyGroups: [ { name: "The Avenue"}, { name: "Broadway" } ] }; // represents new data arriving asynchronously setTimeout(() => { setEstateOverview(newEstateOverview); }, 1000 ); }); return ( <EstateOverview estateName={props.estateName} estateOverview={estateOverview} /> ); }El problema está en EstateOverview:
return ( <List> {props.estateOverview.propertyGroups.map((group) => PropertyGroup(group))} </List> );Esto está intentando representar un componente React llamándolo como una función. Lo que debe hacer, especialmente cuando se trata de componentes funcionales que contienen ganchos:
React.createElementReact.createElement debajo del capó)Esta es la forma correcta de renderizar esto:
return ( <List> {props.estateOverview.propertyGroups.map((group) => <PropertyGroup {...group} />)} </List> );