The network preview whenever i refresh the page will always show duplicate api call (ipaddress)/(portnumber)/admin/user-group?page=1&page_size=10&query= twice. I have tried modifying the useEffect(), handSearch() but to no avail. I'm confident that its because of the use effect() but im having a hard time understanding why. I dont think my other component has any trouble but just in case anyone decided to take a look i'll post one after.
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import SearchBar from './searchTable';
import Pagination from './paginationTable';
interface RowData {
[key: string]: any;
}
interface DynamicTableProps {
columns: string[];
}
const DynamicTable: React.FC<DynamicTableProps> = ({ columns }) => {
const itemsPerPage = 10;
const [currentPage, setCurrentPage] = useState(1);
const [searchValue, setSearchValue] = useState('');
const [filteredRows, setFilteredRows] = useState<RowData[]>([]);
const [isLoading, setIsLoading] = useState(false);
interface UserGroupRow {
id: number;
name: string;
email: string;
phone: string;
count: number;
}
const [totalItems, setTotalItems] = useState(0);
const adminUrl = process.env.NEXT_PUBLIC_ADMIN_URL || '';
const fetchData = async (query: string, page: number, pageSize: number) => {
try {
const token = localStorage.getItem('token');
const headers = {
'token': token ? token : '',
'Content-Type': 'application/json',
};
setIsLoading(true);
const response = await axios.get(`${adminUrl}/admin/user-group?page=${page}&page_size=${pageSize}&query=${query}`, { headers: headers });
if (Array.isArray(response.data.data.user_groups)) {
let formattedRows = response.data.data.user_groups.map((row: UserGroupRow) => {
return {
id: row.id,
name: row.name,
email: row.email,
phone: row.phone,
count: row.count,
};
});
setFilteredRows(formattedRows);
setTotalItems(response.data.meta.total);
} else {
setFilteredRows([]);
}
} catch (error) {
console.error('Error fetching data:', error);
} finally {
setIsLoading(false);
}
};
const fetchDataWrapper = () => {
if (searchValue === '') {
fetchData('', currentPage, itemsPerPage);
} else {
fetchData(searchValue, currentPage, itemsPerPage);
}
};
useEffect(() => {
fetchDataWrapper();
}, [searchValue, currentPage]);
const handleSearch = (searchValue: string) => {
setSearchValue(searchValue);
setCurrentPage(1);
};
const handlePageChange = (newPage: number) => {
setCurrentPage(newPage);
};
return (
<div className="bg-white overflow-hidden shadow-md rounded-md">
<div className="flex items-center justify-end px-6 py-3">
<SearchBar onSearch={handleSearch} />
</div>
<table className="min-w-full divide-y divide-gray-200">
<thead className="bg-gray-50">
<tr>
{columns.map((column) => (
<th
key={column}
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
{column}
</th>
))}
</tr>
</thead>
<tbody className="bg-white divide-y divide-gray-200">
{filteredRows.map((row, index) => (
<tr key={index}>
{columns.map((column) => (
<td key={column} className="px-6 py-4 whitespace-nowrap">
<div className="text-sm text-gray-900">
{row[column] ? row[column] : `No data for ${column}`}
</div>
</td>
))}
</tr>
))}
</tbody>
</table>
<Pagination
currentPage={currentPage}
totalItems={totalItems}
itemsPerPage={itemsPerPage}
onPageChange={handlePageChange}
/>
</div>
);
};
export default DynamicTable;
UPDATE : I separate it into another component to debug the problem, heres what i did. The original problem no matter what i did to modify the useEffect() it will always cause the API to be called twice
import { useState, useEffect } from 'react';
import axios from 'axios';
interface FetchDataOptions {
adminUrl: string;
token: string | null;
query: string;
page: number;
pageSize: number;
}
export const useFetchData = ({
adminUrl,
token,
query,
page,
pageSize,
}: FetchDataOptions) => {
const [data, setData] = useState<any[]>([]);
const [totalItems, setTotalItems] = useState(0);
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
if (!token) return;
const fetchData = async () => {
try {
const headers = {
token,
'Content-Type': 'application/json',
};
setIsLoading(true);
const response = await axios.get(
`${adminUrl}/admin/user-group?page=${page}&page_size=${pageSize}&query=${query}`,
{ headers }
);
if (Array.isArray(response.data.data.user_groups)) {
setData(response.data.data.user_groups);
setTotalItems(response.data.meta.total);
} else {
setData([]);
}
} catch (error) {
console.error('Error fetching data:', error);
} finally {
setIsLoading(false);
}
};
fetchData();
}, [adminUrl, token, query, page, pageSize]);
return { data, totalItems, isLoading };
};