
Join the Conversation!
Subscribing gives you access to the comments so you can share your ideas, ask questions, and connect with others.
Continuing to work on now, let's add some states and get the pagination working! Import and at the top. And inside the function let's create some states:
const [page, setPage] = useState(0);
const [slicedUsers, setSlicedUsers] = useState<User[]>([]);
The first state, , is just like a state we'd create with regular Javascript. The second one, is a little different and leverages Typescript's 'generics'. In typescript- you can create functions and interfaces that are 'generic'. That means they accept and utilize different types.
This is useful if we want to describe something and make it typesafe- but we'll be reusing it for multiple types. For example you may have API responses that always return some type of data in a nested array- but the rest of the response is always the same. You could build out a generic interface to handle all the responses:
interface APIResponse<T>{ // the T is the generic 'type'
responseCode:number;
date:string;
referrer:string;
data:T[];
}
You can then pass in different 'types' as and Typescript would know that the contains a responsecode, a date, a referrer, and an array of whatever type that you passed in was.
const responseForUsers:APIResponse<User> = await fetchUsers();
const responseForPosts:APIResponse<Post> = await fetchPosts();
... etc ...
In our case with our state, is a generic function. We can pass a type in useState<T>, and then typescript and our editor will know that our is an array of Users, and our , should set an array of Users.
Why didn't we have to do that with the other state called ? Just like with all types- you can be explicit or implicit. Because we passed a in to that state, it was implicitly set as a number type. But because we just passed an empty array to our initial state for , we had to explicitly tell typescript that this is actually supposed to be an array of type , we just don't quite have the exact data yet.
Generics are a pretty large topic, but a very powerful tool to understand. You should check the docs out and try to learn how to use them... but it's a little beyond the scope of a crash course like this.
Let's keep building out the pagination. We'll create a under our states that sets the value of our slicedUsers to sets of 5 based on the page we're on.
useEffect(() => {
setSlicedUsers(users.slice(page * 5, page * 5 + 5));
}, [page, users]);
This will run whenever we get our array from the props, and whenever the user clicks a button to change the . This is client-side pagination. We'll change our main to fetch all the pages at once, and then we'll control how many are shown with client-side logic.
Let's update our buttons in the pagination section. We want to add an onClick handler, and I'm going to add a 'data' attribute to the button that we can read in the handler. I like to do this to avoid creating anyonymous functions inside of a map.
{[...Array(5)].map((_, i) => (
<button
key={i}
className="bg-gray-200 rounded-md px-2 py-1"
data-page={i}
onClick={pageClick}
>
{i + 1}
</button>
))}
We can change our className to change the background color if this button is the current 'page' as well:
className={`${
page === i ? "bg-gray-200" : "bg-slate-800"
} rounded-md px-2 py-1`}
Now we'll make the pageClick function.
const pageClick = (e: React.MouseEvent<HTMLButtonElement>) => {
const page = e.currentTarget.dataset.page;
if (page) setPage(parseInt(page));
};
Event Handlers can be tricky with typescript and React. But because you have a basic understanding of how Generics work- it should make sense. We have a generic type that we can pass in more specific types to. In this case, we're clicking a button, so we use the . If we wanted to accurately get the event from other elements on a mouse click, we could pass in their respective type.
<div> -> HTMLDivElement
<a> -> HTMLAnchorElement
<body> -> HTMLBodyElement
... etc ...
If we want to make this handler work for multiple types of elements, there's always which should mean .
It might seem complicated at first- but you just need to break it up into 2 parts:
You'll get used to the event handler names pretty quick- and you'll stop using and cheating ;)
How do I remove the blur effect from my CSS?
I removed but the blur is still there. Any ideas?
filter: blur(5px);
Does work for removing blur from modals?
backdrop-filter: none;
Subscribing gives you access to the comments so you can share your ideas, ask questions, and connect with others.
How did you manage to remove the blur property and reach here?
Upgrading gives you access to quizzes so you can test your knowledge, track progress, and improve your skills.