Placeholder Image

字幕列表 影片播放

  • Hello, everyone.

  • In today's video, we're gonna create a react application that has infinite scrolling built into it.

  • And we're gonna actually use quite a few interesting features of react such as refs and creating our own custom hooks.

  • It's going to be a ton of fun, So let's get started now.

  • Welcome back to Webb.

  • Have simplified my name's Kyle, and my job is to simple by the Web for you.

  • So that sounds interesting.

  • Make sure you subscribe to my channel for more videos just like this one.

  • And to get started on the left hand side, I have visual studio code open, and all I did was run N p x, create react at with a period and this generated all of the bowler employees react code that we're going to need.

  • I then went around and removed all the files.

  • We don't need such a CSS files and such a CZ service workers and test files.

  • So we're just left with her index dot Js and an empty at file to actually put all of our react code inside of also on the right.

  • I have the finished version of our application.

  • All we do is search here for some form of book that we want.

  • This is going to query a book, a p I.

  • So we type and test, for example, and you can see we get a bunch of different results.

  • And when we get to the bottom of page, you see it says, loading right there and then it'll load in our results and you could just continually scroll down until we get to the very end of all of our results.

  • This is just infinitely scroll until there's no more books with the name test inside of their title.

  • Also, something this will do is if we scroll all way back to the top and do a different search.

  • For example, if you search for tea, you see, it'll reset our pagination so that we start all over with our infinite scroll again from the beginning, and it'll clear out all of our old search results for us.

  • So in order to get started, let's actually just create the basic JSX template for application.

  • And we could do that inside of our app here.

  • The first thing that we're going to have is we're gonna have an input component, so it's creative input is going to be a type of text and this is actually going to be here.

  • This input right here.

  • After that, we're going to return some other stuff.

  • So let's put this inside of fragments so we can return the multiple sets of HTML inside of our JSX.

  • That we go in here is where we're gonna put our books.

  • They're gonna be in a div.

  • Never gonna have the title was just copy that down a couple of times that we have an example of what this is going to look like.

  • And then lastly, we're going to have a div which is going to contain loading for when we're loading.

  • And if we have an error, we're gonna have a diff which is going to contain air.

  • So let's save that and actually start our application.

  • Just run NPM run, start.

  • And if we let that run for just a little bit, you see, it's going to start up over on the side here and there you go.

  • You can see that we have our boilerplate html being generated for us and that we can actually work on implementing the AP I and infinite scrolling inside of our application.

  • And to do that, we're going to use Axios to call or a P I.

  • So let's install access by typing in N.

  • P.

  • M.

  • I followed by access, and this one stalled the library access for us, which works a lot like the fetch library does.

  • But it's much easier to use rather than fetch, which can be a bit difficult to use and isn't supported in all browsers.

  • Now that we have that done, we could do all of our code inside of our app for rendering our books, actually querian them, using Axios and doing all that other stuff.

  • But with react and hooks, it's a lot easier to break out our logic into a custom hook.

  • So we're gonna create a custom hook called the Use Book search dot Js.

  • And inside of here we're gonna create a functional component.

  • And if you have the extension installed, which is called S seven React Redux graphic, you'll global boss snippets you could just type R F C and hit enter, and it'll generate all the boilerplate code for you for a function component in react, which is also the same boilerplate code for actually generating a custom hook.

  • We could just remove the JSX because we're not actually going to return JSX.

  • And we also no longer need to import react.

  • But we do want to import use effect just like that, which is going to be the hook that we're gonna be using inside of our custom hook because we want to call or a p I.

  • And that's enough side effect that we want to call every single time Some parameters change.

  • We also want to make sure that we have the used state hook because we're gonna be storing state inside of this custom hook, which we then expose outside of this custom hook by returning it down here in this return.

  • For now, we'll just return north and inside of this component.

  • What we need to do is query that a p I like I mentioned, but we need to take in a few parameters for what we're queen.

  • The first thing we want to take it is the query.

  • Essentially, whatever we type into this text box here, we want to send to our search.

  • We also want to send in here what page number were on because while we are doing infinite scrolling, the way that infinite strolling works is as soon as you get to the bottom of your list of results.

  • It'll query the next page of results from the A.

  • P I and dependent on to the bottom of our page.

  • So we need to know what page number were currently trying to get from the A P I.

  • And once we have those two pieces of information, we can actually set up access inside of an effect.

  • So we can just say, here, use effect.

  • This is going to take a function, which is what we're going to do every single time, that the parameters inside of this array, which is the second argument to use effect, change.

  • And in our case, we want this to happen every time our query or a page number change.

  • And inside of here we can use access to get our information.

  • What's first?

  • Import access from access.

  • We just want to say axis, and this is just a function which is going to take all the parameters that we need to give it.

  • So, for example, a method is going to be a get request.

  • We also need to give it a whirl.

  • I'm just gonna copy this euro from the a p I were using.

  • Essentially, this is the open library, a p I.

  • And we're using the search a p I that they have built in, which has pagination built into it so we can pass that as our parents.

  • So the first thing is our Cleary and in this case, they call that parameter cue in the a p I.

  • So we're gonna pass Q as query and we also need to pass page, which is just our page number variable.

  • And these are things you can find in the A P I documentation for this, a p I.

  • But for example, of q is our quarry and pages the page number that we're on inside of our quick, Also with Axios, this is going to be a promise based thing.

  • So we can just use dot Ben And this first stop then here is going to return us our response.

  • So we have a response variable, and then we can actually do something with that response.

  • And the data of our response is inside of rez dot data and this data we could just Consul, don't walk this for now.

  • And we'll take a look at what this looks like so we can actually understand what our data is doing.

  • So now, back inside of our app Lets import that hook so we can say import use.

  • Look, search.

  • We want to import that from hard dot slash used book search.

  • So now we actually have this hook inside of her application, and we can actually use this hook, for example.

  • We want to pass it our query, and we want to pass it our page number, which right now we don't have stored anywhere.

  • So we need to store these inside of ST.

  • So up here we can just import that used state hook, which will allow us to create some state.

  • And the first thing we can do is set up state for our query.

  • So we have query and set query.

  • We're gonna set this here equal to use state, and by default, our crews is gonna be an empty string.

  • And this use state function returns a query as well as a function to set that query which is going to be render application.

  • What's copy this down and do the same thing for a page number as well as for setting our page number.

  • And by default, we're just gonna have page number one for when we load her application.

  • Now, we actually have these variables being set.

  • We're not updating them anywhere.

  • The easy one to update is our query.

  • So we can just update that in our input, we can set a non change event to this.

  • And we could just saying here we want to call a function called handle search.

  • We can create that function just like this.

  • So say, handle search, and this is going to take the event.

  • And then it's going to actually do some stuff with that vent, which is going to be setting our query so we can say set, query.

  • And we want to set that to ee dot target dot value.

  • And this is just going to be the value of whatever is in the search box.

  • We also want to set our page number back toe one because every time we recre, we want our data results to start at the very first page.

  • We don't want them to start at page seven.

  • If we do a new query Now that that's all done.

  • Let's actually save this Inspector Paige over here and make sure this is working.

  • As we expect for going to the consul Zoom to send a little bit.

  • You can see that we first are getting an object for our buoyant result.

  • But if we query test, we should hear you see get a bunch of results.

  • And this is because we're not canceling our previous request.

  • So every character that we type is actually sending off a request because every character retyped causes this function to run which states are query, which then updates our search.

  • So we're gonna fix that in a little bit.

  • But what I do want to look at is the actual results.

  • We get returned.

  • As you can see, this data has a doc's field, which is all of the different books that were querying.

  • You can see it's a very long list, and inside here we also have the number of results found as well as the start.

  • So this is what page we're currently on.

  • So, for example, start zero, it's page one, and then whatever our pagination number is, which in this case I think is 100.

  • So start 100 would be page number two And this numb found is gonna be really useful for one we know went toe end are infinite scrolling.

  • But to get started, let's worry about this cancellation because we don't want to send a query every single time.

  • We want to cancel our old query if we're typing information.

  • So in a used book search here, Axios has a really easy way to set up cancellations.

  • It takes a parameter called cancel token, and this cancel token is equal to Axios lips.

  • Axios, Doc, cancel token.

  • And we want to create a new one of these.

  • This is actually capital cancel here and inside of this cancel token, it's just going to take a function and dysfunction takes a single parameter, which is going to be the cancel token.

  • And we want to set our own variable to that.

  • So it's creative variable called to cancel, and now we're going to be setting that variable cancel here to the sea from our cancel token.

  • Essentially, this is allowing us to cancel our request and what we can do inside of use effect is if you return something from use effect, you return a function, and then inside that function, we could just call cancel, and this is going to cancel a request every single time.

  • It recalls a used effect.

  • So now let's say that and we can start typing inside of here, and you can see that immediately.

  • We're getting uncaught promises, because every single time that we cancel something, it causes a heir to occur inside of our promise.

  • So it's actually catch that we can say inside of here, we want to catch our air, and what we want to do is we would have checked to see if this is an Axios cancellation error.

  • So luckily, inside access they have built in a really easy way to say is cancel.

  • We just pass it our air, and if so, we just want to return.

  • Essentially, we're saying ignore every single time that we can't still request because we've meant to cancel it.

  • Now if we say that and go over here and start typing, you'll see that only one request is made.

  • No matter how many characters we type, it's only gonna send that one single request, and it's not gonna send a bunch of extra request because it's actually canceling those forests, which is really great.

  • Also inside of this catch, we can return any errors we get so we can actually notify the user of Ares.

  • So now it starts setting up the state inside of our used book search.

  • So we can return this because right now this does nothing.

  • It's just returning no and logging to the consul.

  • But we actually want to return data to our user from this so we can set up our state and we're gonna have a few different things of state.

  • The first thing we're gonna have is loading, so we want a safer loading as well as a way to set loading.

  • And we can say use state.

  • And, of course, by default, we're gonna set our loading to true because the very first thing we're gonna do is load inside of our application.

  • Next, we're gonna set up a error as well was set there, and by default, we're not gonna have an error.

  • So we're just gonna set that to false?

  • The last two pieces of state is we're gonna have our state for our books.

  • This is pretty self explanatory.

  • This is the actual books we get back from our A p.

  • I call and we want this Just be an empty array to start with because we have no books being found and then a little bit more confusing piece of state we want is a has more as well.

  • A set has more.

  • And we're gonna set this here to use state and by default, what is gonna set that to false Just in case there is no more results and this has more essentially is telling us when we get to that numb found, as you can see, their 79,000 results.

  • If we somehow scroll through all those we don't want to keep making requests to the A P I because there is no more results.

  • So so essentially prevent us from making request that we don't really want to make.

  • Now that we have over state set up, let's actually start setting the state inside of her application.

  • So the first thing we wanna do is every time we make a request, we want to set loading to be true because we're now loading.

  • We want to set our error to be false because we no longer have an heir because we're starting a brand new request which hopefully will succeed instead of fail.

  • Also inside of our dot.

  • Then here we can set our state for our books so we can say set books, and this is actually going to be using the function version of seven State, which allows us to take the previous state, which in our case is previous books.

  • So we can actually modify our previous books and we want to do is we're gonna return our previous books combined with our new books so we could say previous books, and we want to spread that as well as we want to add in.

  • Here are new books, which is going to be our rez dot data dot docks.

  • As you can see over here, we have Open this up, Doc.

  • Doc's this is going to be our books and we want a map over that because we just want the title of our books.

  • So we're gonna have a book here.

  • We just want to get b dot title because this is the title of our book and we don't care about anything else One thing to note, though, is that this actually is going to return to us a list of variables where we could have multiple titles, because this data actually does things beyond just the title of the book and actually has additions and other things.

  • So it may have multiple titles that are exactly the same, and we want to remove those.

  • And a really easy way to do that is which what's called a set, essentially a set in JavaScript.

  • You can pass it in a ray, and it's going to return just unique values.

  • It's not gonna return any of the other information, so we're gonna have only the unique titles, and all we need to do is convert this back to an array by just spreading over our entire set.

  • It's a little bit confusing, but essentially what we're doing is we're combining our old books with our new books, and then we're converting it to a set.

  • So we remove all the duplicates and they were converting it back to an array so we could do all of our normal array manipulation, such as looping and mapping that we want to do later.

  • So now that we have our books set.

  • What's also set our has more and has more is gonna be pretty simple.

  • We just want to check here if the rez dot data flip stop data dot docks dot length is greater than zero, which essentially means that we have no more data because there's no books returned to us so that we know that we never need to make this query again.

  • Also, we can set our loading here to false because we're no longer voting our data.

  • Also, instead of our catch, we want to set our heir to be true because we actually do have an error that is coming from our results.

  • Something went wrong with our a p I.

  • So we want to make sure we make note of that.

  • And now that we have all these different variables being set, we can actually return these to our user.

  • So down here in our return, we can return an object, and the object is going to contain loading.

  • It's going to contain error books as well as has more.

  • So now all of the state from our hook is being returned from this hook and we can use it inside of our app.

  • So now here we can say that we want a constant variable.

  • It's going to be equal to this and we're gonna d structure out.

  • Our books are has more than a D structure out loading as well as air.

  • So now we have all of the different variables from our used book search that we have available instead of her application.

  • And we can actually start rendering some of this information.

  • For example.

  • We can come in here and actually render out of books so we can say books dot map so we can loop over all of our books and for each book.

  • What we want to do is we just want to call a function here.

  • And this function is just going to print out a div so we can just say return div.

  • We need to give it a key because in react, when you ever you render a list of items from an array, you need a unique key, which, in our case, we're gonna put our book in there because these are the titles of our book on.

  • We know their unique.

  • Since we use that set property to make sure we only returned unique books.

  • And then we can just put the name of the book in here as well.

  • Also, our loading we can put in if we are loading, then we want to put the text of loading dot, dot, dot Unless just copy this down exact same thing for air.

  • But instead we're gonna say air and we can remove this air down here.

  • And now if we save this close out of this council and we just typing test, for example, you can see it says loading.

  • And then we get the list of all of our different books.

  • Well, you will notice our books aren't quite being structured, right?

  • And that's because in our used book search, I forgot to actually spread out our results.

  • So now if we save this and do a new search for test, you should see we're getting all the results perfectly in here.

  • But of course, there's no pagination set up yet, but that's okay.

  • We're gonna work on that now.

  • But there's still one bug If we scroll back up to the top and let's say we change our query to be just t R T There we go.

  • And now you can see that our results are actually being upended on to the end.

  • We have all of our T results as well as our test results.

  • So what we need to do inside of our used book search is use another effect, and this effect is going to be a very small effect.

  • And all it's going to do is every single time that we change our query we're gonna set.

  • Here are books, so we're gonna say set books.

  • We just want to set it back to an empty ray.

  • So every time we change our query, we're gonna reset our book array so that we don't have any of our old books being shown up.

  • Now, if we save this search for test, you see, we get all of our test results.

  • If we change it to t, you can see we're just gonna get our t results back, which is perfect.

  • Now, with all of that out of the way, we can finally work on the part that you've been waiting for, which is setting a pagination.

  • So if we go back to our app here, one thing that I forgot to do this, that our value here, what's of value to our query.

  • So just make sure we do that that way, just in case we change our query somewhere else.

  • It'll be updated inside of this input field.

  • Also to set up pagination, we need to use what are called with the refs instead of react So we could just come in here and say, Use what, ref?

  • And a ref is essentially a value that persist after each render because inside of wrecked, every single thing that we do is on Lee stored inside that render unless it's part of our state.

  • But if we want to store something between renders that isn't part of our state, we need to use ref.

  • And rough is really great when you need to store references to elements.

  • For example, if we want to get a reference to our books element or input element, or if you want to get a reference to something that's related to the document a p I and in our case we're using intersection of Server, which is part of the document a p I.

  • So it's creative variable what you gonna do it all the way up here, we're gonna say constant observer is going to be equal to use ref just like that.

  • And by default, the first time this gets ran issues going tohave undefined as the value, which is okay.

  • We also need to get a reference to the very last book element.

  • Because what we're gonna do is we're gonna make it so that when we scroll all the way down and that our very last book element in our case, Scandinavian Cooking is showing on the screen.

  • Then we actually want toe change our page number and add one to it.

  • So Intersection Observer is going to allow us to say when something's on our screen.

  • But we need to get a new element reference to that very last element in our books array in order to know which element is the last one.

  • And you would think we could just do this with use, ref.

  • But like I mentioned use ref is not part of our state.

  • So it doesn't update every single time that it changes.

  • So when our reference changes, it doesn't actually rerun our component.

  • So we're gonna use is use call back and this actually has a really unique interaction with use ref, where if we set a ref, for example, if we said ref is equal to and we used a use ref So if I just come up here and say const last book element, ref and I said it equal to use call back and I actually supplied information here, we could set that reference down here and now what's gonna happen is whenever this element is created, it's going to call the function inside of use.

  • Call back with the reference to the element that we're using down here.

  • So it's gonna call a function which is going to have knowed, for example, as the perimeter.

  • And this node corresponds to this individual element right here.

  • We only want to do this for our very last book.

  • So it's put in a simple If check here.

  • And we can just say that if our books dot length is equal to index plus one and we could just use the index inside of our map like this, we can say index is the second property to Matt.

  • So if, for example, are length of our books is equal to our index plus one.

  • Essentially, this is the very last book.

  • Then what we want to do is we want to return this because we want to get a reference to that very last book.

  • Otherwise, if it's not the last book we want to do almost the exact same thing.

  • But we no longer need this ref anymore.

  • So we could just return a normal div just like that.

  • Now, if I come up here and I just want to put in something that says comes of that log node so we can see that this is working.

  • And if we save this search for test and if I inspect our page, you can see that that last book, which is Scandinavian cooking, is getting logged out to us.

  • So it's calling this last book element, ref, every single time we render that component.

  • Now all we have left to do is actually set up our intersection observer in here.

  • So we know wonder on our last element.

  • So the first thing we can do is we can say if loading.

  • So we want to check if we're loading, then we just want to return.

  • Because if we're loading our information, we don't want to trigger our infinite scrolling.

  • Otherwise, it'll just constantly call the AP I while we're loading and we definitely don't want that.

  • So with out of the way, next thing we need to do is we want to check to see if we have an observer.

  • So the way refs work is they have a variable property called current, which is whatever the current iteration of that variable is.

  • So if we have an observer we're going to do is we want to disconnect that observer because we're gonna reconnect it so we can save her Observer, doc current dot disconnect call that function.

  • This is going to disconnect our observer from the previous element.

  • So that way, our new last element will be hooked up correctly.

  • And we just make sure we check our observer because, as you remember, by default, this is going to be no the very first time around.

  • The next thing we need to do is set our current observer so we can say observer dot current is going to be equal to a new intersection observer, and this is going to take in a function and dysfunction takes all the entries that are available.

  • So everything that it's watching is going to be in this entries array as soon as they become visible, we're gonna implement this function and just a little bit.

  • But we want to finish out our function here by saying, if we have a node.

  • So, for example, if something is actually our last element, we just want to make sure that our observer is observing it.

  • So we get our current observer and we can you say that we want to observe our node just like that?

  • And just like all the other callbacks that you get with hooks, we actually need to return a list of dependencies on our case, our dependencies air going to be loading.

  • As Wallace has more the's.

  • There are only two dependencies that we're going to be messing with.

  • And now inside of this function, we can implement this.

  • So the first thing you want to check is if entries and we want to get our first entry because we're only ever observing one single note.

  • So if our know that we're observing, we want to say if it's intersecting, essentially, that means it's on the page somewhere.

  • Then we're just gonna console that log visible so we can actually see if this is working.

  • And of course, we're getting an air, and that's just because this hook down here, which is actually getting our loading information, I need to just move this up so that it's above the code that's actually using that loading.

  • So just put it all the way at the top here and now if we say this, that air should go away.

  • Perfect.

  • Now we can type in test and you can see nothing's getting log.

  • But as soon as we get to the very bottom of our page and that element becomes visible, you'll see it gets logged out that it's visible, which is exactly what we want.

  • And inside of this code, we can actually add one toe our page so we could just say Set page number, lips, set page number.

  • We want to get our previous page number, and what we're gonna do is add one to that.

  • So it's a previous page number plus one just like that, and also the last thing we need to check inside of here is if we have more.

  • So the reason we're checking has more is if we're out of elements to query essentially r a p.

  • I has queried all the data.

  • We don't want to continually keep calling this a p I.

  • So this won't allow us to keep paginated forever because otherwise it would just paginated forever.

  • So I want to save this and see if this works.

  • If we typing test and we scroll all the way to the bottom are Page, you can see we get a text loading and it allows us to scroll some more and we get loading again.

  • And if we search something that's a little bit more specific so we can test to see if our has more works, we could say The Lord of the Rings.

  • And now it's loading.

  • And as soon as that's done loading, we can see that we can screw all the way down its load in scroll a little bit more loading.

  • Keep going.

  • You can see we got loading again and hopefully we're getting close to the ant eared.

  • As you can see, that's the very end.

  • The loading went away and it's not trying to keep querian r a p I.

  • It just completely stopped, which is exactly what we want, and that's all it takes to set up infinite scrolling with react.

  • If you enjoyed this video, make sure check on my other videos linked over here and subscribe to the channel for more videos like this one.

  • Thank you very much for watching and have a good day.

Hello, everyone.

字幕與單字

單字即點即查 點擊單字可以查詢單字解釋

A2 初級

用React無限滾動--教程 (Infinite Scrolling With React - Tutorial)

  • 9 0
    林宜悉 發佈於 2021 年 01 月 14 日
影片單字