Auto Refresh React Table upon success of the delete action server side - reactjs

How can i refresh the react-table upon editing/deleting a data (server-side based), Here's my code so far
import React,{useState,useEffect} from 'react'
import { useTable, usePagination } from 'react-table'
// import {TableContainer} from './?'
import Table from './TableContainer'
import axios from 'axios';
// Let's add a fetchData method to our Table component that will be used to fetch
// new data when pagination state changes
// We can also add a loading state to let our table know it's loading new data
function App() {
const columns = React.useMemo(
() => [
{
Header: 'Name',
columns: [
{
Header: 'name',
accessor: 'name',
},
{
Header: 'Last Name',
accessor: 'lastName',
},
],
},
{
Header: 'Info',
columns: [
{
Header: 'Age',
accessor: 'age',
},
{
Header: 'Visits',
accessor: 'visits',
},
{
Header: 'Status',
accessor: 'status',
},
{
Header: 'Profile Progress',
accessor: 'progress',
},
{
Header: 'Action',
accessor: '',
id: 'edit',
accessor: 'id',
Cell: ({value}) => (<button onClick={() => editData(value)} data-id={value}>Edit</button>)
},
],
},
],
[]
)
// We'll start our table without any data
const [data, setData] = React.useState([])
const [loading, setLoading] = React.useState(false)
const [pageCount, setPageCount] = React.useState(0)
const [ totalPages, setTotalPages ] = useState(0);
const [ sizePerPage, setSizePerPage ] = useState(10);
const [ page, setPage ] = useState(0);
const [ filtered, setFiltered ] = useState("");
const fetchIdRef = React.useRef(0)
const fetchData = React.useCallback(({ pageSize, pageIndex,filtered }) => {
console.log(filtered);
setLoading(true);
axios.get(`http://127.0.0.1:8000/api/schools?q=${filtered}&sizePerPage=${pageSize}&page=${pageIndex+1}`)
.then((res)=> {
setData(res.data.data);
setSizePerPage(res.data.meta.per_page)
setPage(res.data.meta.current_page)
setPageCount(Math.ceil(res.data.meta.total / pageSize))
setLoading(false)
});
}, [])
function editData(name) {
setLoading(true);
console.log(name)
console.log(sizePerPage);
axios.delete(`http://127.0.0.1:8000/api/schools/${name}`)
.then((res) =>{
// fetchData(sizePerPage);
})
}
return (
<Table
columns={columns}
data={data}
fetchData={fetchData}
loading={loading}
pageCount={pageCount}
filtered={filtered}
filterable
/>
)
}
export default App
When I call the fetch data upon the response, it can't access the callback param of pageSize,pageIndex, filtered I've already try to call it with params but it gives me an error that the pageSize,pageIndex are now undefined
What am I doing wrong?

Related

React Material-UI: Populating Rows in DataGrid returns undefined

In my React application, I want to fill the rows of a Material-UI Data Grid with backend data.
To achieve this, I make a GET request to the backend, which returns an AxiosResponse containing the data.
This AxiosResponse, I store in a variable named list, using useState().
Afterwards, I iterate over list to map the data to an Array of Objects, named testrows.
In the return method with DataGrid, I want to set property row to testrows.
However on rendering, it returns an error saying that testrow is undefined.
What am I doing wrong here?
import ...
export default function FruitList() {
const [list, setList] = useState<AxiosResponse>();
const columns: GridColDef[] = [
{
field: 'id',
headerName: 'Fruit ID',
type: 'number',
},
{
field: 'type',
headerName: 'Fruit Type',
type: 'string',
},
{
field: 'harvest',
headerName: 'Harvest Date',
type: "date",
},
{
field: 'entryDate',
headerName: 'Entry Date',
type: "date",
},
];
// Get list of fruits and store in variable "list"
useEffect(() => {
axios.get('http://localhost:3000/v1/fruit/'
.then(result => {
setList(result);
})
}, [])
let testrows = list?.data.map((element: { id: any, type: any, harvest: any, entryDate: any }) => {
return {
id: element.id,
type: element.type,
harvest: element.harvest,
entryDate: element.entryDate
}
}
);
// also tried useMemo:
const testrows = useMemo(() =>
list?.data.map((element: { id: any, type: any, harvest: any, entryDate: any }) => {
return {
id: element.id,
type: element.type,
harvest: element.harvest,
entryDate: element.entryDate
}
}),
[list?.data]
);
// console output: "test: undefined"
console.log("test: ", testrows);
return (
<div>
<div>
<DataGrid
rows={testrows}
columns={columns}
/>
</div>
</div>
);
}

Exporting const to another file in React

I have a table component that is reusable with different column props. My app uses the component several times, and many times I use the same columns but not all. So I'm trying to export my "const columns = ..." to a separate file. the problem is it can't be a pure function, because I'm using useMemo and numeral... how can I move the my columns to a separate file so they can be accessed by multiple tables or defined separately if needed?
//App.js
import React from 'react'
import styled from 'styled-components'
import { useTable } from 'react-table'
import numeral from "numeral";
import makeData from './makeData'
function Table({ columns, data }) {
// Use the state and functions returned from useTable to build your UI
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
} = useTable({
columns,
data,
})
// Render the UI for your table
return (
<table {...getTableProps()}>
<thead>
{headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
<th {...column.getHeaderProps()}>{column.render('Header')}</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map((row, i) => {
prepareRow(row)
return (
<tr {...row.getRowProps()}>
{row.cells.map(cell => {
return <td {...cell.getCellProps()}>{cell.render('Cell')}</td>
})}
</tr>
)
})}
</tbody>
</table>
)
}
function App() {
const columns = React.useMemo(
() => [
{
Header: 'Name',
columns: [
{
Header: 'First Name',
accessor: 'firstName',
},
{
Header: 'Last Name',
accessor: 'lastName',
},
],
},
{
Header: 'Info',
columns: [
{
Header: 'COH',
accessor: 'age',
Cell: (props) => (
<div className="color1">
{numeral(props.value).format("$0,0.000")}
</div>
),
},
{
Header: 'Visits',
accessor: 'visits',
},
{
Header: 'Status',
accessor: 'status',
},
{
Header: 'Profile Progress',
accessor: 'progress',
},
],
},
],
[]
)
const MobileColumns = React.useMemo(
() => [
{
Header: 'Name',
columns: [
{
Header: 'First Name',
accessor: 'firstName',
},
{
Header: 'Last Name',
accessor: 'lastName',
},
],
},
{
Header: 'Info',
columns: [
{
Header: 'COH',
accessor: 'age',
Cell: (props) => (
<div className="color1">
{numeral(props.value).format("$0,0.000")}
</div>
),
},
],
},
],
[]
)
const data = React.useMemo(() => makeData(20), [])
return (
<>
<div className="hide-mobile">
<Table columns={columns} data={data} />
</div>
<div className="show-mobile">
<Table columns={MobileColumns} data={data} />
</div>
</>
)
}
export default App
I attempted to create a new file called Columns.js like so, but I can't use useMemo there it seems.
// Columns.js
import React, { useMemo } from "react";
import numeral from "numeral";
export const columns = React.useMemo(
() => [
{
Header: 'Name',
columns: [
{
Header: 'First Name',
accessor: 'firstName',
},
{
Header: 'Last Name',
accessor: 'lastName',
},
],
},
{
Header: 'Info',
columns: [
{
Header: 'COH',
accessor: 'age',
Cell: (props) => (
<div className="color1">
{numeral(props.value).format("$0,0.000")}
</div>
),
},
{
Header: 'Visits',
accessor: 'visits',
},
{
Header: 'Status',
accessor: 'status',
},
{
Header: 'Profile Progress',
accessor: 'progress',
},
],
},
],
[]
)
export const MobileColumns = React.useMemo(
() => [
{
Header: 'Name',
columns: [
{
Header: 'First Name',
accessor: 'firstName',
},
{
Header: 'Last Name',
accessor: 'lastName',
},
],
},
{
Header: 'Info',
columns: [
{
Header: 'COH',
accessor: 'age',
Cell: (props) => (
<div className="color1">
{numeral(props.value).format("$0,0.000")}
</div>
),
},
],
},
],
[]
)
};

Using Firebase Database with React-Table

I have some difficulties in trying to make React-Table work with Firebase Database.
I have this logic to get the data from a Firebase DB:
const servicesCollectionRef = collection(db, "service");
const [serviceRequests, setServiceRequest] = useState([]);
const fetchServiceRequest = async () => {
const response = await getDocs(servicesCollectionRef);
const querySnapshot = await getDocs(servicesCollectionRef);
console.log(querySnapshot.docs);
querySnapshot.forEach((doc) => {
console.log(`${doc.id} => ${JSON.stringify(doc.data())}`);
});
setServiceRequest(querySnapshot.docs)
};
useEffect(() => {
fetchServiceRequest();
}, []);
What I don't understand is how can I save the data, because in my console I get this when logging the console.log(querySnapshot.docs):
(2) [Mu, Mu]
0: Mu {_firestore: La, _userDataWriter: dh, _key: Dt, _document: Gt, _converter: null, …}
1: Mu {_firestore: La, _userDataWriter: dh, _key: Dt, _document: Gt, _converter: null, …}
length: 2
[[Prototype]]: Array(0)
How do I have to save my db data or how do i have to acces it in order to also have the columns for React-Table work:
const data = useMemo(() => [...serviceRequests], [serviceRequests]);
const columns = useMemo(
() => [
{
Header: "Cerere",
columns: [
{
Header: "Id",
accessor: "id",
},
{
Header: "Email",
accessor: "Email",
},
{
Header: "Nume",
accessor: "NumeClient",
},
{
Header: "Prenume",
accessor: "PrenumeClient",
},
{
Header: "Pachet",
accessor: "Pachet",
},
{
Header: "Pret",
accessor: "Pret",
},
],
},
{
Header: "Asignare Medic",
columns: [
{
Header: "Medic",
accessor: "Nume",
},
],
},
],
[]
);
// const tableInstance = useTable({ columns, data });
Thank you in advance!

MaterialUI Data-Grid Loading Animation Infinite Loop

I am using Material-UI Data-Grid, and I'm running a tutorial grid for server-side data access. This is written in React, and I'm having a problem that the loading circle is permanently spinning. I set a breakpoint in React.useEffect and I see it getting hit over and over and over. handlePageChange doesn't seem to be participating in the infinite loop.
Thinking about this a little, I feel that the state is changing which triggers the whole thing to execute again, hence the loop. What is the condition supposed to be to stop the thing?
import * as React from 'react';
import { DataGrid } from '#material-ui/data-grid';
function loadServerRows(page, data) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(data.rows.slice(page * 5, (page + 1) * 5));
}, Math.random() * 500 + 100); // simulate network latency
});
}
export default function App() {
const data = {
rows: [
{ id: 1, col1: 'Hello', col2: 'World' },
{ id: 2, col1: 'XGrid', col2: 'is Awesome' },
{ id: 3, col1: 'Material-UI', col2: 'is Amazing' },
],
columns: [
{ field: 'col1', headerName: 'Column 1', width: 150 },
{ field: 'col2', headerName: 'Column 2', width: 150 },
],
rowLength: 100,
maxColumns: 6
}
const [page, setPage] = React.useState(0);
const [rows, setRows] = React.useState([]);
const [loading, setLoading] = React.useState(false);
const handlePageChange = (params) => {
setPage(params.page);
};
React.useEffect(() => {
let active = true;
(async () => {
setLoading(true);
const newRows = await loadServerRows(page, data);
if (!active) {
return;
}
setRows(newRows);
setLoading(false);
})();
return () => {
active = false;
};
}, [page, data]);
return (
<div style={{ height: 400, width: '100%' }}>
<DataGrid
rows={rows}
columns={data.columns}
pagination
pageSize={5}
rowCount={100}
paginationMode="server"
onPageChange={handlePageChange}
loading={loading}
/>
</div>
);
}
In your code data changes on each render. As an option, you can store data with useRef (or just make it global moving out of component):
import React from 'react'
import { DataGrid } from '#material-ui/data-grid'
function loadServerRows(page, data) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(data.rows.slice(page * 5, (page + 1) * 5))
}, Math.random() * 500 + 100) // simulate network latency
})
}
function App() {
const data = React.useRef({
rows: [
{ id: 1, col1: 'Hello', col2: 'World' },
{ id: 2, col1: 'XGrid', col2: 'is Awesome' },
{ id: 3, col1: 'Material-UI', col2: 'is Amazing' },
],
columns: [
{ field: 'col1', headerName: 'Column 1', width: 150 },
{ field: 'col2', headerName: 'Column 2', width: 150 },
],
rowLength: 100,
maxColumns: 6
})
const [page, setPage] = React.useState(0)
const [rows, setRows] = React.useState([])
const [loading, setLoading] = React.useState(false)
const handlePageChange = (params) => {
setPage(params.page)
}
React.useEffect(() => {
let active = true;
(async () => {
setLoading(true)
const newRows = await loadServerRows(page, data.current)
if (!active) {
return
}
setRows(newRows)
setLoading(false)
})()
return () => {
active = false
}
}, [page, data])
return (
<div style={{ height: 400, width: '100%' }}>
<DataGrid
rows={rows}
columns={data.current.columns}
pagination
pageSize={5}
rowCount={100}
paginationMode="server"
onPageChange={handlePageChange}
loading={loading}
/>
</div>
)
}

I want to call FetchData function from Constants.js page

This is my code:
import { SetCommonButtons} from "../../../../Utils/Constants";
const Main = () => {
const setButton = (cell, row) => {
return SetCommonButtons(row)
};
const Columns = [
{
dataField: "status",
text: "Action",
editable: false,
formatter: setButton,
},
];
const FetchData = () => {
List(Id).then((response) => {
});
};
};
export default Main;

Resources