javascript - My component does not re-render the contents of <Table> - Stack Overflow

admin2025-04-17  2

I am trying to create a hook in my application made on Create React App, but when updating the constant that contains the information, the component that shows the list on the screen is not rendered again, but the list is updated, since the hook returns it updated in console (it is worth mentioning that when loading the component for the first time, it is rendered correctly, but it is not updated when the information changes).
Sales List

import React, { use, useState, useEffect } from 'react';
import { Table } from 'antd';
import UpdateList from '../hooks/updateList';

const SalesList = () => {
    const { list, loading, error, updateList } = UpdateList();

    useEffect(() => {
        updateList();
    }, []); /* If I add updateList within the [], it works, but it enters an infinite loop */

    useEffect(() => {
        console.log('List updated in the component:', list);
    }, [list]);

    const columns = [
        {
            title: 'Name',
            dataIndex: 'name',
            key: 'name',
        },
        {
            title: 'Price',
            dataIndex: 'price',
            key: 'price',
        },
        {
            title: 'Quantity',
            dataIndex: 'quantity',
            key: 'quantity',
        },
        {
            title: 'Amount Received',
            dataIndex: 'amountReceived',
            key: 'amountReceived',
        },
    ];

    if (loading) return <div>Loading...</div>;
    if (error) return <div>Error: {error.message}</div>;

    return <Table dataSource={list} columns={columns} rowKey="ID" />;
};

export default SalesList;

UpdateList

import { useState, useEffect } from 'react';
import useFetchData from '../services/api/showData';

const UpdateList = () => {
    const { data, loading, error, fetchData } = useFetchData();
    const [list, setList] = useState([]);

    const updateList = async () => {
        try {
            const newList = await fetchData();
            setList([...newList]);
            console.log('New list obtained:', newList);
        } catch (error) {
            console.error('An error occurred while updating your data', error);
        }
    };

    useEffect(() => {
        updateList();
    }, [fetchData]);

    return { list, loading, error, updateList };
};

export default UpdateList;

ShowData

import { useState, useEffect, useCallback } from "react";
import axios from 'axios';

const useFetchData = () => {
    const [data, setData] = useState([]);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState(null);

    const fetchData = useCallback(async () => {
        setLoading(true);
        try {
            const response = await axios('http://localhost/REACT/my-app/src/backend/php/api/mostrarDatos.php');
            if (!response.data.ok) {
                return console.error('An error occurred, please restart. If the issue persists, contact the administrator.');
            }
            setData(response.data.respuesta);
            return response.data.respuesta;
        } catch (error) {
            setError(error instanceof Error ? error : new Error("An unknown error occurred"));
            console.error("Error fetching data:", error);
            return [];
        } finally {
            setLoading(false);
        }
    }, []);

    useEffect(() => {
        fetchData();
    }, [fetchData]);

    return { data, error, fetchData };
};

export default useFetchData;

I need that when updating the constant lista, the component that creates the table is updated, the hook is working but it is not re-rendering the data.

I am trying to create a hook in my application made on Create React App, but when updating the constant that contains the information, the component that shows the list on the screen is not rendered again, but the list is updated, since the hook returns it updated in console (it is worth mentioning that when loading the component for the first time, it is rendered correctly, but it is not updated when the information changes).
Sales List

import React, { use, useState, useEffect } from 'react';
import { Table } from 'antd';
import UpdateList from '../hooks/updateList';

const SalesList = () => {
    const { list, loading, error, updateList } = UpdateList();

    useEffect(() => {
        updateList();
    }, []); /* If I add updateList within the [], it works, but it enters an infinite loop */

    useEffect(() => {
        console.log('List updated in the component:', list);
    }, [list]);

    const columns = [
        {
            title: 'Name',
            dataIndex: 'name',
            key: 'name',
        },
        {
            title: 'Price',
            dataIndex: 'price',
            key: 'price',
        },
        {
            title: 'Quantity',
            dataIndex: 'quantity',
            key: 'quantity',
        },
        {
            title: 'Amount Received',
            dataIndex: 'amountReceived',
            key: 'amountReceived',
        },
    ];

    if (loading) return <div>Loading...</div>;
    if (error) return <div>Error: {error.message}</div>;

    return <Table dataSource={list} columns={columns} rowKey="ID" />;
};

export default SalesList;

UpdateList

import { useState, useEffect } from 'react';
import useFetchData from '../services/api/showData';

const UpdateList = () => {
    const { data, loading, error, fetchData } = useFetchData();
    const [list, setList] = useState([]);

    const updateList = async () => {
        try {
            const newList = await fetchData();
            setList([...newList]);
            console.log('New list obtained:', newList);
        } catch (error) {
            console.error('An error occurred while updating your data', error);
        }
    };

    useEffect(() => {
        updateList();
    }, [fetchData]);

    return { list, loading, error, updateList };
};

export default UpdateList;

ShowData

import { useState, useEffect, useCallback } from "react";
import axios from 'axios';

const useFetchData = () => {
    const [data, setData] = useState([]);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState(null);

    const fetchData = useCallback(async () => {
        setLoading(true);
        try {
            const response = await axios('http://localhost/REACT/my-app/src/backend/php/api/mostrarDatos.php');
            if (!response.data.ok) {
                return console.error('An error occurred, please restart. If the issue persists, contact the administrator.');
            }
            setData(response.data.respuesta);
            return response.data.respuesta;
        } catch (error) {
            setError(error instanceof Error ? error : new Error("An unknown error occurred"));
            console.error("Error fetching data:", error);
            return [];
        } finally {
            setLoading(false);
        }
    }, []);

    useEffect(() => {
        fetchData();
    }, [fetchData]);

    return { data, error, fetchData };
};

export default useFetchData;

I need that when updating the constant lista, the component that creates the table is updated, the hook is working but it is not re-rendering the data.

Share Improve this question asked Feb 1 at 0:48 Emmanuel SalazarEmmanuel Salazar 214 bronze badges 5
  • 1 If UpdateList is supposed to be a custom React hook then it should be named like one, i.e. named using a "use-" prefix, e.g. useUpdateList. Why does UpdateList effectively duplicate the fetched data state and effect? useFetchData also doesn't return a defined loading property value. When updateList/fetchData is/are called does any new data get returned? Have you checked/verified that the AntD Table component rerenders when passed a different dataSource prop value? – Drew Reese Commented Feb 1 at 0:59
  • Please edit your question to provide more background details on your problem. Telling readers about your research, what you have already tried, and why it didn’t meet your needs will allow them to understand it better. – Drew Reese Commented Feb 1 at 1:00
  • Do you get any errors in the browser's console? – Kostas Minaidis Commented Feb 1 at 1:37
  • I would suggest that you take the sample dataSource found in the docs (ant.design/components/table) and compare with the response that you get from your php endpoint. If replacing the endpoint response with the sample data and the Table renders correctly, then it's probably a malformed table data that you are passing to the Table. – Kostas Minaidis Commented Feb 1 at 1:39
  • 1 Hi, First of all let us clear the intent of the code. The list is fetched and rendered in the initial render. This is fine. After that what should happen ? Is there any state change in the frontend to retrieve data again ? if not, how do want to get the updated data, is it based on timer ? – WeDoTheBest4You Commented Feb 1 at 3:32
Add a comment  | 

1 Answer 1

Reset to default 0

Custom hook's function name should always start with 'use' as per react best practices and docs. Your 'useFetchData' follows this condition and hence can be considered a hook. But 'UpdateList' looks more like a react component than a hook. You can change it to 'useUpdateList' to make it more coherent and clear.

Also you need not return the function that is used to make the API call like that since you are returning the list that is being fetched using the API.

Also you are setting data in your useFetchData but you are not using it anywhere. You can try the following:

In your useFetchData,

const useFetchData = () => {
    //......
    return {data, loading, error}
}

In your SalesList component, you can call your useFetchData directly.

const SalesList = () => {
    const { list, loading, error } = useFetchData();
    //.......
}
转载请注明原文地址:http://anycun.com/QandA/1744842684a88386.html