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.

Antd Cascader no muestra los hijos cuando se aplica los datos obtenidos de una API con SWR.

Estoy intentando usar el componente Cascader de Ant Design pero ha ocurrido un problema cuando apliqué los datos obtenidos de una API con el SWR Hook.

Mi código:

“`
const { dataCategories: { data }} = useCategories(); //SWR custom hook para reutilizar en otros componentes

/*
Obtuve el resultado después de la obtención:

[
{
cate_id: 1,
cate_name: ‘Apple’,
has_children: true,

},
{
cate_id: 2,
cate_name: ‘Asus’,
has_children: true,

},
{
cate_id: 3,
cate_name: ‘Dell’,
has_children: true,

}
]
*/

const [options, setOptions] = useState(data);

const loadData = async selectedOptions => {

const targetOption = selectedOptions[selectedOptions.length – 1];
targetOption.loading = true;
setTimeout(() => {
targetOption.loading = false;
targetOption.children = [
{
cate_name: ‘iPhone’,
cate_id: 1,
has_children: false,
},
{
cate_name: ‘Macbook’,
cate_id: 2,
has_children: false,
}
];
setOptions([…options]);
}, 2000);

};

return (

({ …e, isLeaf: !e.has_children }) )}
loadData={loadData}
changeOnSelect
placeholder=”Por favor seleccione su categoría”
/>

)

Actualmente, muestra los elementos, pero cuando hago clic en cada elemento para abrir el cascader de hijos, siempre está girando y no responde.
¿Qué estoy haciendo mal?

Tags:  ,

Answer

  1. Avatar for davy.ai

    Basado en el código y la explicación proporcionados, parece que el problema está relacionado con la naturaleza asíncrona de la función loadData y la forma en que actualiza el estado de options.

    Cuando el usuario hace clic en un elemento para abrir sus descendientes en cascada, se llama a la función loadData para obtener y cargar los datos de las opciones secundarias. Sin embargo, esta función establece la propiedad loading de la opción objetivo en true y luego realiza una operación asíncrona (es decir, un setTimeout) para simular una recuperación de datos. Durante este tiempo, el estado de options se actualiza con los valores originales (ya que options se pasa como una dependencia a setOptions) y el componente se vuelve a renderizar con estos datos incompletos.

    Cuando se completa la operación asíncrona, la propiedad loading de la opción objetivo se restablece a false y la propiedad children se actualiza con los datos recuperados. Sin embargo, en lugar de establecer el estado de options con las opciones actualizadas (es decir, la opción objetivo con sus descendientes), se llama a setOptions con el array de opciones original ([...options]), lo que provoca que el componente se vuelva a renderizar con los datos incompletos una vez más. Esto crea un bucle infinito de actualizaciones y re-renderizaciones, lo que conduce al comportamiento de giro y la falta de respuesta.

    Para solucionar este problema, debes actualizar el estado de options con el array de opciones actualizadas que incluya la opción objetivo con sus descendientes. Puedes lograr esto encontrando el índice de la opción objetivo en el array de options y actualizándolo con los nuevos valores utilizando el operador de propagación (spread operator). Luego, puedes establecer el estado de options con el array actualizado utilizando setOptions.

    Aquí tienes el código actualizado para la función loadData:

    const loadData = async (selectedOptions) => {
      const targetOption = selectedOptions[selectedOptions.length - 1];
    
      targetOption.loading = true;
    
      try {
        const fetchedData = await fetchChildren(targetOption.cate_id); // obtener datos secundarios de la API
    
        targetOption.children = fetchedData.map((child) => ({
          ...child,
          isLeaf: !child.has_children,
        }));
    
        const targetIndex = options.findIndex((option) => option.cate_id === targetOption.cate_id);
        const updatedOptions = [...options];
        updatedOptions[targetIndex] = targetOption;
    
        setOptions(updatedOptions);
      } catch (error) {
        // manejar error
        targetOption.loading = false;
      }
    };
    

    Ten en cuenta que este código actualizado utiliza una función fetchChildren para obtener los datos secundarios de la API en lugar de la función setTimeout. Esta función debería definirse fuera del componente y puede utilizar la API fetch o cualquier biblioteca (por ejemplo, Axios) para realizar la solicitud a la API y devolver los datos.

    Además, se agrega un bloque try/catch para manejar cualquier error que pueda ocurrir durante la recuperación de la API, y la propiedad loading de la opción objetivo se restablece a false en el bloque catch para manejar correctamente el estado de carga.

    Con estos cambios, el componente en cascada debe cargar y mostrar los datos correctamente, sin girar ni volverse irresponsivo.

Comments are closed.