How to print/render in a table Firebase information REACT JS - javascript

Before posting I always google, youtube, forums or try to figure it by myself or even check other people questions that are similar but I'm stuck sadly.
So I'm using firestore database, the user can create a "student" and the data is the firestore is saved like this:
It saves the course, Name, school, and the UID of the person that create it. So far I have no problems importing that information to the firestore now the issue is to bring it back in a table, I do not understand why is not being printed.
The console Log is printing all the students 1 by 1 + all the students in the array (is cause is going through all the info)
Now as you can see the table is empty! and I do not understand WHY!!! Very frustrated
This are snips of the code that are relevant:
DB part:
useEffect(() => {
db.collection('usuarios').doc(user.uid).collection('estudiantes')
.get().then((snapshot) => {
(snapshot.forEach(doc => {
const data = doc.data();
estudiantes.push(data)
console.log(doc.data());
console.log(estudiantes)
}))
})
}, []);
Map/Rendering
<tbody>
{estudiantes.map((e) => (
<tr >
<td>
<input onChange = {(event) => {
let checked = event.target.checked;
}}
type="checkbox" checked = "">
</input>
</td>
<td >{e.name}</td>
<td >{e.school}</td>
<td >{e.grade}</td>
<td></td>
</tr>
))}
</tbody>
Whole Code:
import React, { useState, useEffect } from 'react'
import { auth, db } from './firebase';
import "./ListadoEstudiantes.css"
import data from "./mock-data.json"
import { useHistory } from 'react-router-dom';
import { Checkbox } from '#material-ui/core';
function ListadoEstudiantes({user}) {
const [contacts, setContacts] = useState(data);
const history = useHistory("");
const crearEstudiante = () => {
history.push("/Crear_Estudiante");
}
const realizarPedidos = () => {
history.push("/Crear_Pedidos");
}
const estudiantes = [];
useEffect(() => {
db.collection('usuarios').doc(user.uid).collection('estudiantes')
.get().then((snapshot) => {
(snapshot.forEach(doc => {
const data = doc.data();
estudiantes.push(data)
console.log(doc.data());
console.log(estudiantes)
}))
})
}, []);
return (
<div className="listadoEstudiantes">
<div className="estudiantes_container">
<h1 className = "estudiantes_container_h1">Listado de estudiantes</h1>
<button onClick={crearEstudiante} className = "crear_estudiante_boton">Crear Estudiantes</button>
<h3 className = "estudiantes_container_h3">*Para realizar su pedido seleccione a los estudiantes</h3>
<div className ="tableContainer">
<table>
<thead>
<tr className="Lista">
<th>
<input type="checkbox"></input>
</th>
<th>Nombre</th>
<th>Colegio</th>
<th>Grado</th>
<th>Accion</th>
</tr>
</thead>
<tbody>
{estudiantes.map((e) => (
<tr >
<td>
<input onChange = {(event) => {
let checked = event.target.checked;
}}
type="checkbox" checked = "">
</input>
</td>
<td >{e.name}</td>
<td >{e.school}</td>
<td >{e.grade}</td>
<td></td>
</tr>
))}
</tbody>
</table>
</div>
<div className="space" />
<button onClick={realizarPedidos} className = "crear_estudiante_boton">Realizar Pedidos</button>
<div className="space" />
</div>
</div>
)
}
export default ListadoEstudiantes
I think that's it, the user is from the Firestore database also the data that I'm importing is a fake data that I used to test the table (and renders with no issues) that can be ignored.
This is how it looks on the fake data and how it should look with the real data (THAT DOESN'T WORK! :'3)

estudiantes should be a local state of the component. Therefore, it needs to be captured as a state and use it for table data rendering as follows.
setEstudiantes is a setState function which updates the state asynchornously. Therefore, in order to check the updated state, you need to have the console.log("estudiantes: ", estudiantes) inside the render method (not after setEstudiantes(tempData)). Otherwise, you won't be able to see the updated state.
import React, { useState, useEffect } from "react";
import { auth, db } from "./firebase";
import "./ListadoEstudiantes.css";
import data from "./mock-data.json";
import { useHistory } from "react-router-dom";
import { Checkbox } from "#material-ui/core";
function ListadoEstudiantes({ user }) {
const [contacts, setContacts] = useState(data);
const [estudiantes, setEstudiantes] = useState([]);
const history = useHistory("");
const crearEstudiante = () => {
history.push("/Crear_Estudiante");
};
const realizarPedidos = () => {
history.push("/Crear_Pedidos");
};
useEffect(() => {
db.collection("usuarios")
.doc(user.uid)
.collection("estudiantes")
.get()
.then((snapshot) => {
const tempData = [];
snapshot.forEach((doc) => {
const data = doc.data();
tempData.push(data);
console.log(doc.data());
console.log("Temp Data: ", tempData);
});
setEstudiantes(tempData);
});
}, []);
console.log("estudiantes: ", estudiantes);
return (
<div className="listadoEstudiantes">
<div className="estudiantes_container">
<h1 className="estudiantes_container_h1">Listado de estudiantes</h1>
<button onClick={crearEstudiante} className="crear_estudiante_boton">
Crear Estudiantes
</button>
<h3 className="estudiantes_container_h3">
*Para realizar su pedido seleccione a los estudiantes
</h3>
<div className="tableContainer">
<table>
<thead>
<tr className="Lista">
<th>
<input type="checkbox"></input>
</th>
<th>Nombre</th>
<th>Colegio</th>
<th>Grado</th>
<th>Accion</th>
</tr>
</thead>
<tbody>
{estudiantes.map((e) => (
<tr>
<td>
<input
onChange={(event) => {
let checked = event.target.checked;
}}
type="checkbox"
checked=""
></input>
</td>
<td>{e.name}</td>
<td>{e.school}</td>
<td>{e.grade}</td>
<td></td>
</tr>
))}
</tbody>
</table>
</div>
<div className="space" />
<button onClick={realizarPedidos} className="crear_estudiante_boton">
Realizar Pedidos
</button>
<div className="space" />
</div>
</div>
);
}
export default ListadoEstudiantes;

Related

How to display different tables on click in React?

I am making a simple todo. I am fetching data from an API and I want to show all the items in a table by default. There will be 3 buttons - All, Complete and Incomplete which will show All, Completed and Incompleted todos table respectively. I have set states for completed and incompleted todos but can't wrap my head around how to perform conditional rendering and display different tables on different button clicks.
Below is my code -
import React, { useState, useEffect } from "react";
import axios from "axios";
import "./style.css";
export default function App() {
const URL = 'https://jsonplaceholder.typicode.com/todos';
const [todo, setTodo] = useState([]);
const [completed, setCompleted] = useState([]);
const [incomplete, setIncomplete] = useState([]);
useEffect(()=>{
axios.get(URL)
.then(res=>setTodo(res.data));
},[])
const showCompleted = () =>{
const completeTask = todo.filter((items)=>items.completed===true);
setCompleted(completeTask);
}
const showIncomplete = () =>{
const incompleteTask = todo.filter((items)=>items.completed===false);
setIncomplete(incompleteTask);
}
return (
<div>
<h1>ToDos!</h1>
<button type="button">All</button>
<button type="button" onClick={showCompleted}>Completed</button>
<button type="button" onClick={showIncomplete}>Incomplete</button>
<hr />
<table>
<tr>
<th>ID</th>
<th>Title</th>
<th>Completed</th>
</tr>
{todo.map((items)=>
<tr key={items.id}>
<td>{items.id}</td>
<td>{items.title}</td>
<td><input type="checkbox" defaultChecked={items.completed ? true : false} /></td>
</tr>
)}
</table>
</div>
);
}
Instead of maintaining a separate state for each type have one type state that the buttons update when they're clicked. Add data attributes to the buttons to indicate what type they are and which can be picked up in the click handler.
Instead of mapping over the whole set of todos, call a function that filters out the set of data from the todo state that you need.
const { useEffect, useState } = React;
const URL = 'https://jsonplaceholder.typicode.com/todos';
function Example() {
const [todos, setTodos] = useState([]);
const [type, setType] = useState('all');
useEffect(()=>{
fetch(URL)
.then(res => res.json())
.then(data => setTodos(data));
}, []);
// Filter the todos depending on type
function filterTodos(type) {
switch(type) {
case 'completed': {
return todos.filter(todo => todo.completed);
}
case 'incomplete': {
return todos.filter(todo => !todo.completed);
}
default: return todos;
}
}
// Set the type when the buttons are clicked
function handleClick(e) {
const { type } = e.target.dataset;
setType(type);
}
// Call the filter function to get the
// subset of todos that you need based
// on the type
return (
<div>
<h1>ToDos!</h1>
<button
type="button"
className={type === 'all' && 'active'}
data-type="all"
onClick={handleClick}
>All
</button>
<button
type="button"
className={type === 'completed' && 'active'}
data-type="completed"
onClick={handleClick}
>Completed
</button>
<button
type="button"
className={type === 'incomplete' && 'active'}
data-type="incomplete"
onClick={handleClick}
>Incomplete
</button>
<hr />
<table>
<tr>
<th>ID</th>
<th>Title</th>
<th>Completed</th>
</tr>
{filterTodos(type).map(todo => {
const { id, title, completed } = todo;
return (
<tr key={id}>
<td>{id}</td>
<td>{title}</td>
<td>
<input
type="checkbox"
defaultChecked={completed ? true : false}
/>
</td>
</tr>
);
})}
</table>
</div>
);
}
ReactDOM.render(
<Example />,
document.getElementById('react')
);
button { margin-right: 0.25em; }
button:hover { cursor:pointer; }
.active { background-color: lightgreen; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Keep two states, one to store the initial data and another one to keep track of actually displayed data.
Try like this:
function App() {
const URL = "https://jsonplaceholder.typicode.com/todos";
const [todo, setTodo] = React.useState([]);
const [view, setView] = React.useState([]);
React.useEffect(() => {
fetch(URL)
.then((res) => res.json())
.then((result) => {
setTodo(result);
setView(result);
});
}, []);
const showAll = () => {
setView(todo);
};
const showCompleted = () => {
const completeTask = todo.filter((items) => items.completed === true);
setView(completeTask);
};
const showIncomplete = () => {
const incompleteTask = todo.filter((items) => items.completed === false);
setView(incompleteTask);
};
return (
<div>
<h1>ToDos!</h1>
<button type="button" onClick={showAll}>
All
</button>
<button type="button" onClick={showCompleted}>
Completed
</button>
<button type="button" onClick={showIncomplete}>
Incomplete
</button>
<hr />
<table>
<thead>
<tr>
<th>ID</th>
<th>Title</th>
<th>Completed</th>
</tr>
</thead>
<tbody>
{view.map((items) => (
<tr key={items.id}>
<td>{items.id}</td>
<td>{items.title}</td>
<td>
<input
type="checkbox"
defaultChecked={items.completed ? true : false}
/>
</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
ReactDOM.render(<App />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<div class='react'></div>
You can use useMemo to prepare the data to display based on some conditions/filters/search/ordering/ anything else.
So few steps to achieve that:
Optional, declare some object outside of the component to hold some constants. Maybe I choosed a poor name for that but the idea itself should be ok. FILTER_COMPLETED in the code.
Add a useState variable to hold active filter for this specific area. const [filterCompleteMode, setFilterCompleteMode] = useState(...) in the code.
Add a useMemo variable that will prepare the data to display. You can apply some ordering or additinal filtering here. todosToDisplay in the code.
Modify your JSX a bit, change <button>s and todo to todosToDisplay.
const { useState, useMemo, useEffect } = React;
const FILTER_COMPLETED = {
All: "ALL",
Complete: "COMPLETE",
Incomplete: "INCOMPLETE"
};
function App() {
const URL = "https://jsonplaceholder.typicode.com/todos";
const [todos, setTodos] = useState([]);
const [filterCompleteMode, setFilterCompleteMode] = useState(
FILTER_COMPLETED.All
);
const todosToDisplay = useMemo(() => {
if (!todos) return [];
switch (filterCompleteMode) {
case FILTER_COMPLETED.All:
return todos;
case FILTER_COMPLETED.Incomplete:
return todos.filter((x) => x.completed === false);
case FILTER_COMPLETED.Complete:
return todos.filter((x) => x.completed === true);
default:
return todos;
}
}, [todos, filterCompleteMode]);
useEffect(() => {
fetch(URL)
.then((res) => res.json())
.then((data) => setTodos(data));
}, []);
const onCompleteFilterClick = (e) => {
setFilterCompleteMode(e.target.dataset.mode);
};
return (
<div>
<h1>ToDos!</h1>
<button
type="button"
data-mode={FILTER_COMPLETED.All}
onClick={onCompleteFilterClick}
>
All
</button>
<button
type="button"
data-mode={FILTER_COMPLETED.Complete}
onClick={onCompleteFilterClick}
>
Completed
</button>
<button
type="button"
data-mode={FILTER_COMPLETED.Incomplete}
onClick={onCompleteFilterClick}
>
Incomplete
</button>
<hr />
<table>
<thead>
<tr>
<th>ID</th>
<th>Title</th>
<th>Completed</th>
</tr>
</thead>
<tbody>
{todosToDisplay.map((item) => (
<tr key={item.id}>
<td>{item.id}</td>
<td>{item.title}</td>
<td>
<input
type="checkbox"
defaultChecked={item.completed ? true : false}
/>
</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
ReactDOM.createRoot(document.getElementById("root")).render(<App />);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>
<div id="root"></div>
Create state:
const [whatShow, setWhatShow] = useState('All').
When you click on button change this state
next:
{todo.map((items)=>
{items.completed === whatShow && <tr key={items.id}>
<td>{items.id}</td>
<td>{items.title}</td>
<td><input type="checkbox" defaultChecked={items.completed ? true : false} /></td>
</tr>}
)}
something like this

Delete Table Row not working properly with search bar

i'm new to reactjs and i'm trying to make a table that shows the information from a array of objects and have a button of delete and an input to search among the users. The delete button is working correctly when i'm not searching anything, but when i'm searching it doesn't delete the corretly row, and deletes only the first one. I see that it is because the arrays that show the table are different with and without the search being used but I don't know how to make it work.
this is the component of the table:
import { formatDate } from "../../utils/formatDate";
import "./table.css";
import { useState } from "react";
function Table(props) {
const { headerData, bodyData, type, removeItem} = props;
const isUser = type === "user";
const buildTableItems = () => {
return bodyData.map((item, index) => (
<tr className="data-tr">
<td>{item.name}</td>
<td>{item.email}</td>
<td>{item.occupation}</td>
<td>{formatDate(item.birthday)}</td>
<td>
<button className="delete-button" onClick={() => removeItem(index)}>
Delete
</button>
</td>
</tr>
));
};
return (
<div className="user-data">
<table className="user-table">
<thead>
<tr className="data-th">
{headerData.map((headerTable) => (
<th >{headerTable}</th>
))}
</tr>
</thead>
<tbody>{buildTableItems()}</tbody>
</table>
</div>
);
}
export default Table;
Here the component of the search bar:
import "./searchBar.css"
function SearchBar({ searchedData, onSearch }) {
return (
<div className="search-bar">
<label>Search</label>
<input type="text" placeholder="Search User" value={searchedData} onChange={e => onSearch(e.target.value)} />
</div>
);
}
export default SearchBar;
and here is the home:
import "./Home.css";
import React, { useEffect, useState } from "react";
import Header from "../components/Header/Header";
import Table from "../components/Table/Table";
import AddData from "../components/AddData/AddData";
import SearchBar from "../components/SearchBar/SearchBar";
import { userArr } from "../mock/users";
const Home = () => {
const headerUser = ["Name", "Email", "Occupation", "Birthday"];
const [newUserArr, setNewUserArr] = useState(userArr);
const [searchedItem, setSearchedItem] = useState("");
const searchedArray = newUserArr.filter((item) => {
if (item.name.toLowerCase().includes(searchedItem.toLowerCase())) {
return true;
}
});
function onSearch(e) {
setSearchedItem(e);
}
const addDataToArr = (form) => {
setNewUserArr([...newUserArr, form]);
};
const deleteData = (indexUserArr) => {
let restOfDataArray = newUserArr.filter(
(element, ind) => ind !== indexUserArr
);
setNewUserArr(restOfDataArray);
};
return (
<>
<Header />
<SearchBar searchedData={searchedItem} onSearch={onSearch} />
<Table
type="user"
headerData={headerUser}
bodyData={newUserArr}
removeItem={(index) => deleteData(index)}
/>
<AddData saveData={(val) => addDataToArr(val)} />
</>
);
};
export default Home;
thank you
If you have ID in your user data then use that instead of index or create id keywords using concatenate with your values here is examples.
import { formatDate } from "../../utils/formatDate";
import "./table.css";
import { useState } from "react";
function Table(props) {
const { headerData, bodyData, type, removeItem} = props;
const isUser = type === "user";
const buildTableItems = () => {
return bodyData.map((item, index) => (
<tr className="data-tr">
<td>{item.name}</td>
<td>{item.email}</td>
<td>{item.occupation}</td>
<td>{formatDate(item.birthday)}</td>
<td>
<button className="delete-button" onClick={() => removeItem(`${item.name}${item.email}${item.occupation}`)}>
Delete
</button>
</td>
</tr>
));
};
return (
<div className="user-data">
<table className="user-table">
<thead>
<tr className="data-th">
{headerData.map((headerTable) => (
<th >{headerTable}</th>
))}
</tr>
</thead>
<tbody>{buildTableItems()}</tbody>
</table>
</div>
);
}
export default Table;
And here is your delete method ${item.name}${item.email}${index}
const deleteData = (data) => {
let restOfDataArray = newUserArr.filter(
(element, ind) => `${element.name}${element.email}${element.occupation}` !== data
);
setNewUserArr(restOfDataArray);
};
This will fixed your problem. If this doesn't work then you need to use ID to resolve this problem. There is a possibility that ${item.name}${item.email}${item.occupation} can be duplicates.
Never use index ever for deleting or any other operations. Use always ID.

How can I fetch the username and image from diff schema to UI?

I want to fetch the username of those people who order under the user ID. Is it possible to grab the owner of the id and render it to the UI using userId? instead of rendering the actual userId.
It came from different schema in database,
import React, { useEffect, useState } from 'react'
import { format } from 'timeago.js'
import { userRequest } from '../../requestMethod'
import './Widgetlg.css'
const WidgetLg = () => {
const Button = ({ type }) => {
return <button className={'widgetLgButton ' + type}>{type}</button>
}
const [orders, setOrders] = useState([])
useEffect(() => {
const getOrders = async () => {
//this is just a shorcut api
try {
const res = await userRequest.get('orders')
setOrders(res.data)
console.log(res.data)
} catch (error) {
console.log(error)
}
}
getOrders()
}, [])
return (
<div className="widgetLg">
<h3 className="widgetLgTitle">Latest Transactions</h3>
<table className="widgetTable">
<tr className="widgetLgTr">
<th className="widgetLgTh">Customer</th>
<th className="widgetLgTh">Date</th>
<th className="widgetLgTh">Amount</th>
<th className="widgetLgTh">Status</th>
</tr>
{orders.map((order) => (
<tr className="widgetLgTr">
<td className="widgetLgUser">
<span className="WidgetLgName"> {order.userId} </span>
</td>
<td className="widgetLgDate"> {format(order.createdAt)} </td>
<td className="widgetLgAmmount">P {order.amount} </td>
<td className="widgetLgStatus">
<Button type={order.status} />
</td>
</tr>
))}
</table>
</div>
)
}
export default WidgetLg
How can I fetch and render the owner of the given userId?
UI
As Best as can tell you need to get a joint document or join query and create a simple endpoint that you can call at once at the ui side using axios.

How to implement pagination to a list data in a table in react.js?

Quick help needed! I have list of data rendered in a table from an API. I need this list of data to be paginated into small list of data.
Here is the code for VendorsDetail.js which displays list of data in a table
import React, { useState, useEffect } from "react";
import HelpOutlineIcon from "#mui/icons-material/HelpOutline";
import axios from "axios";
import VendorDetailsBrief from "./VendorDetailsBrief";
import Pagination from "./Pagination";
const VendersDetail = ({ textMe }) => {
const [data, setData] = useState({});
const foo = "cpe:2.3:a:oracle:peoplesoft_enterprise:8.22.14";
const baseURL =
"https://services.nvd.nist.gov/rest/json/cves/1.0?cpeMatchString=" + foo;
useEffect(() => {
axios
.get(baseURL)
.then((response) => {
setData(response.data);
})
.then(
(response) => {},
(err) => {
alert(err);
}
);
}, []);
const DisplayData = data?.result?.CVE_Items?.map((vender) => {
return (
<tr>
<td className="color_id font-semibold">
{vender?.cve?.CVE_data_meta?.ID}
</td>
<td className="w-96">
{vender?.cve?.description?.description_data?.[0]?.value}
</td>
<td>{vender?.impact?.baseMetricV2?.exploitabilityScore}</td>
<td>{vender?.impact?.baseMetricV2?.severity}</td>
<td>{vender?.impact?.baseMetricV2?.impactScore}</td>
</tr>
);
});
return (
<div className="z-100 flex justify-center items-center mt-10">
<div className="text-black">
<div className="rounded overflow-hidden flex justify-center items-center">
<table class="table table-striped ">
<thead>
<tr>
<th>Vuln ID</th>
<th>Description Data</th>
<th>Exploitability Score</th>
<th>Severity</th>
<th>Impact Score</th>
</tr>
</thead>
<tbody>{DisplayData}</tbody>
</table>
</div>
</div>
</div>
);
};
export default VendersDetail;
Pagination.js
import React from "react";
const Pagination = ({ postsPerPage, totalPosts, paginate }) => {
const pageNumbers = [];
for (let i = 1; i <= Math.ceil(totalPosts / postsPerPage); i++) {
pageNumbers.push(i);
}
return (
<nav>
<ul className="pagination">
{pageNumbers.map((number) => (
<li key={number} className="page-item">
<a onClick={() => paginate(number)} href="!#" className="page-link">
{number}
</a>
</li>
))}
</ul>
</nav>
);
};
export default Pagination;
How can I implement pagination in this particular data list? Thanks
Create Parent Component with logic to get data from URL and pagination onCLick handler.
Parent Component should render VendorsDetail component and Pagination component.
Pass data to be displayed to VendorsDetails component and getSubsequentData handler to Pagination component.
If user click on specific page number, call getSubsequentData handler with specific argument, that updates the state of the parent component, which will updates VendorsDetail component.
const ParentComponent = () => {
const [data, setData] = useState({})
useEffect = (() => {
// axios call to get initial data from the URL
})
getSubsequentData = (URL) => {
// axios call to get data based on the URL.
// LInk this to pagination onClick
}
return(
<VendorsDetail data={data} />
<Pagination getNextData={getSubsequentData}/>
)
}

React table loads but disappears on clicking pagination links

I am new to React and trying to develop my first web application. What I am trying to achieve is pretty basic. I am trying to fetch some data from an API and display it in a table. To the table I am trying to add pagination so that all the records are not displayed on the same screen. I have added the page numbers but when I click on any of the page number links, the correct data in the table gets loaded but the table disappears immediately. I have no clue why this is happening. Here is my code below:
Basket.js
import React, { useState, useEffect } from "react";
import axios from "axios";
import Posts from "../Posts";
import Pagination from "../Pagination";
const Basket = () => {
const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(false);
const [currentPage, setCurrentPage] = useState(1);
const [postsPerPage] = useState(10);
useEffect(() => {
const fetchPosts = async () => {
setLoading(true);
const res = await axios.get("http://192.168.29.135:8000/aysle/baskets/");
setPosts(res.data);
setLoading(false);
};
fetchPosts();
}, []);
//Get current posts
const indexOfLastPost = currentPage * postsPerPage;
const indexOfFirstPost = indexOfLastPost - postsPerPage;
const currentPosts = posts.slice(indexOfFirstPost, indexOfLastPost);
//Change Page
const paginate = (pageNumber) => setCurrentPage(pageNumber);
//console.log(posts);
return (
<div>
<Posts posts={currentPosts} loading={loading} />
<Pagination
postsPerPage={postsPerPage}
totalPosts={posts.length}
paginate={paginate}
/>
</div>
);
};
export default Basket;
To display the data in tabular form am using the below code:
Posts.js:
import React from "react";
import edit from "../images/edit.png";
import del from "../images/delete.png";
import "./Basket/basket.scss";
const Posts = ({ posts, loading }) => {
if (loading) {
return <h2>Loading All Baskets....</h2>;
}
return (
<table className="basket-view">
<thead>
<tr id="Baskettr">
<th id="Basketth" colSpan="4">
Here are your Listings...
</th>
</tr>
<tr id="Baskettr">
{/* <th id="Basketth">Id</th> */}
<th id="Basketth">Basket Name</th>
<th id="Basketth">Basket Creation Date</th>
<th id="Basketth">Basket Modified Date</th>
<th id="Basketth">Action</th>
</tr>
</thead>
<tbody id="Baskettbody">
{posts ? (
posts.length > 0 ? (
posts.map((post, index) => {
return (
<tr id="Baskettr" key={index}>
{/* <td id="Baskettd">{basket.id}</td> */}
<td id="Baskettd">{post.basket_name}</td>
<td id="Baskettd">{post.basket_creation_date}</td>
<td id="Baskettd">{post.basket_modified_date}</td>
<td>
<button id="delBtn" title="Edit">
<img src={edit} id="BtnImg" alt="Edit" />
</button>
<button id="editBtn" title="Delete">
<img src={del} id="BtnImg" alt="Delete" />
</button>
</td>
</tr>
);
})
) : (
<tr id="Baskettr">
<td id="Baskettd">No Records to Show...</td>
</tr>
)
) : (
0
)}
</tbody>
</table>
);
};
export default Posts;
And finally, for pagination I am using the following code:
import React from "react";
const Pagination = ({ postsPerPage, totalPosts, paginate }) => {
const pageNumbers = [];
//console.log(totalPosts);
for (let i = 1; i <= Math.ceil(totalPosts / postsPerPage); i++) {
pageNumbers.push(i);
}
return (
<nav>
<ul className="pagination">
{pageNumbers.map((number) => (
<li key={number} className="page-item">
<a onClick={() => paginate(number)} href="!#" className="page-link">
{number}
</a>
</li>
))}
</ul>
</nav>
);
};
export default Pagination;
Please help me to rectify this issue. Thanks a lot for your time in advance. Here is the CodeSandBoxLink
It's all because of the href attribute "!#" in the tag. Because of it, there is a transition to a new page and all data fetched again.
You can use <button/> instead of <a/> and style it with css. example

Categories

Resources