React Query 3 - CRUD Library Application

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everyone my name is maxim ivanov and in this video we're going to build a crowd application a library book storing app using react query version 3. first of all let me show you the final result here is the app we have a list of books we can add new books here title sum book by some author submit you see a nice preloader here a nice preloader there and it's here in the list now we can edit this book some book becomes some other book submit here you go it's updated and you can remove the item boom so if you're not subscribed yet do it now press the like button and let's go so we're gonna create a crowd application using react and react query version three and we already have an api using node.js and it's documented using swagger don't worry i'm going to provide you with this server the link will be in the description and if you want to know how to write and document your api server using swagger then let me know in the comments here we have a library api you can see that we have a bunch of endpoints we can get a list of all the books we can try it out right here in the browser if i press execute it will actually perform the request and we'll get a response with the books that we currently have in our library then we can also get info for a particular book let's copy an id for example this one copy and then we press try it out paste the book id and press execute and we get this particular book description then we can also update the book by its id let's try to update the previous book paste id and then let's say we just add a bunch of pluses press execute and the book was updated if we refetch the list of the books let's clear it and execute again you will see that one of them the one that we've edited has now pluses in the author name we can also create new books there is a post handle post and then we press try it out let's remove the id it's going to be generated automatically and let's call it test test the title is test and the author is going to be test as well execute we got the new book we have an id now if we fetch the list of the books it's going to be in this list somewhere yeah it's here in the bottom and we can also remove this book delete try it out let's paste the id and press execute this book was removed and if we fetch the list of the books you will see that it's not there anymore it was removed let's begin by creating a new react application i'm going to be using create react up npx create react app and i'm going to call it client after it's done we switch to the client folder cd client and open the code editor first of all we'll need to install a bunch of dependencies first of all i'm going to install react query because that's a tutorial about the react query library right so install yarn add react query we'll also need something to implement the navigation between pages i'm going to be using react router dom react router dom we're going to be using react hook form to handle the forms in our application so react hook form also i'll need to style the app and i'm going to be using rebas for this application i'm going to install rebas and also rebase forms and re-bass preset for theming i'm also going to install styled components here i also use them for theming and finally i'm going to use react loader spinner for animated loaders react loader spinner after it's done and you have all the dependencies you have rebus forms rebus preset react hook form react loader spinner react query router dome rebas and style components we can begin working on our application and first i'm going to remove a bunch of files i'm going to remove test because it's going to become irrelevant very soon i'm going to remove the logo and i'm also going to remove the app.css file boom then we go to index.js and perform the initial setup first of all let's import the browser router from react router dom browser router from react router dom and we wrap our application into it browser router next we'll need the theme provider and we'll get it from the style components import theme provider from styled components we're going to use it with a preset from rebas import preset from rebase preset and now we wrap our application into it theme provider theme equals preset and then a closing tag format the document and finally we prepare the react query we'll need to import query client provider and the query client itself from react query and then wrap our application into it query client provider and then we specify that client before we can do it we need to instantiate it so we create a const query client equals new query client and now we can pass it as a prop query client query client is an object that allows you to interact with your cache we'll actually use it once when we'll need to clear the books cache when we'll remove the book and we'll need to refresh the list of the books on the page and the query client provider is a provider that makes your query client accessible across the whole application now before we move on we'll also need to import the styles for the react loader spinner let's do it import react loader spinner dist loader css react spinner loader css and now we should be all set up let's go to app.js and plan our routes first of all remove the imports and then remove all the layout now we need to import the switch component import switch and also the route component from the react router dom route from react router dom let's go to the app component use the switch this component allows you to render the routes exclusively so if the first of them matches then only this route will be rendered and first we'll define the route route route path route and a closing tag and inside of it we'll render the books list component the books list component is a page so i'm going to create a folder for it new folder books list inside of it i'm going to create a new file also called bookslist.jsx and i'm also going to create an index file index.js this file will make it easier to access the books list component and kind of harder or the default level of hardness to access the books list specific components for example we'll use the book item to represent the book in the list and we don't want this component to be used on any other pages so we'll make it easier to use the books list by exporting export everything from the books list module from this module and here we'll export a new component expert const books list equals a function and for now return nothing let's go back to the app and import the books list component import books list from books list and as you can see i'm importing from the kind of folder itself and i can do this only because i have this index.js file that re-exports the entities in our case the component from the books list module so i don't have to write books list slash books list even though i can but in my case i don't want to do this and it's intentional so that if i ever see that someone on some other page is trying to use dot dot to get one folder up and then books list and then some component from it then i know that something is going wrong and some other page instead of using the shared files is trying to use the specific files components from another module and this is what i want to avoid here so i'm going to have a convention in this app that if you want to import something from a specific page you do it like this and if it's not exported from the index then you're not supposed to use it and let's continue let's format the document and then we define another route we'll need the route to create a book let's define it route path let's call it create whoa slash create book then we add a closing tag route and inside of it we use a component called create book again it's a page so i think it deserves its own folder new folder create book same as with the book list i create a file called create book.jsx and an index file index dot js i create a component and export it export const create book equals a function that returns nothing for now return null and inside of the index file i export everything from create book i import the create book component from the create book module and now we define our last route which is update book i'm gonna copy this part of the layout change the create to update and change the actually change the create update here as well update and i repeat the process create a new folder update book inside of it i create a new file update book.jsx and an index file index.js export everything from update book and i import this component import update book from the update book module all right we have the navigation structure and we have the folder for each of the pages i like this structure because this way when you open the folder for this particular page you can see what files does it have and if you have the test files they will be in the same folder along with the component itself so for example for create book there would be another file called create book spec or test dot jsx and it's just nice because you immediately see that some of the components are not tested by the way in this tutorial we are not going to write the tests for the components but if you would like to see a tutorial on how to test each of those components and test the whole application then write a comment below this video and i'm going to do it next time let's remove the file for now and next thing we do we create a shared folder because we are going to have a bunch of shared components for example here above the switch i want to have a navigation bar i'm going to use a fragment to wrap all the elements and then here i want to have a navbar and it will go to the shared folder let's create a new folder new folder shared and we create a new file here nav bar the jsx here we export a const called nav bar which is a function and here we return actually something we're going to return the navbar layout and i'm going to use components from the rebas it's going to help me quite a lot because they're already styled and it's going to save me a bunch of time so before we begin let's actually import those components import i'm going to use flex component it's a container with the display flex set by default we're going to use a box that's the default container in rebas we're going to use a link but we're also going to be using links from the react order dom inside of this component so i'm going to rename it to a styled link link as styled link and i'm also going to be using an image component for a logo in the top left corner and we import it from rebas style components you can use the default versions which are meant to be used with the emotion styling system but as i've used the theme provider from the style components i need to use the styled components inputs next we're going to import the link component from the react router dom that's what i was talking about the names they overlap this is why i renamed the styled link link from react router dom now let's start working on the layout the topmost component is going to be the flex is going to have bg black color is going to be a font color white and justify content is going to be center we're going to center the elements here next we add another flex container that will contain our elements it's going to have the padding 2 it's going to have width 100 and it's going to have the align items property center now inside of it we're going to use a link and this one is from react router dom and we're going to set the component of this link to be the styled link from the rebas variant nav and the link component will propagate this all other props to the styled link component that we're using here variant nav and to the root route this link will say react query crowd then we'll use the box is going to be a spacer margin horizontal mx equals auto so it will take the horizontal space between the react query crowd link and the create new book or add new book link on the right actually i'm going to copy the previous link i don't like to type link component installed link the url will be create book and the text should be plus add new book and actually we forgot to close the box tag actually now is a good time to test if everything works let's make sure that we've imported the nav bar inside of the app component which we did not do so we do import navbar from shared nav bar and the shared folder is the only one where i i'm gonna allow or i'm gonna expect that people will use specific imports now let's launch the app yarn start open the browser and that's what you should see you should see the link to the root route and the link to the create book route nothing else should be shown on the screen because we didn't implement those pages but at least the navbar is here before we move on i'm going to create another component that is going to limit the width of our application it's going to be a container and let's do it now and also i'm going to use the icon for the react query to make the app look nicer let's do it inside the shared folder create a new file call it container dot jsx inside of it we import the box from the rebas and as we are using styled components to provide the theme we need to use the style components import now we export the container component expert cons container equals a function and here we return a simple layout with a box we actually need to get the children from the props because it's going to be a wrapping component we render the children inside of the box and this box is going to have some styles based on the theme so we pass an object as an sx prop width 100 max width 1024 and margin horizontal mx aura now we go back to navbar we import our container component import container from container and then right inside the outermost flexbox container we add our container component container and here we add the closing tag for it format the document and now let's add the icon i'm going to copy the icon from another project cp react query 3 client src shared logo svg and we copy it to src shared now inside of the nav bar we import logo from logo svg and here is this file before the react query crowd link we add an image size 20 src logo and a closing tag no closing slash i'm going to launch the app again and then after we open it in the browser we should see the icon and everything should be centered now let's continue with the books list page open the books list component and here we're gonna start working with react query let's import a bunch of things first of all we need to import the use query hook use query use query is used to fetch the data use query from react query and when you call it you get a bunch of things we're interested in data that we're going to fetch an error if something wrong happens the flag for the loading status that is called is loading and the flag for an error which is called ease error let's define the constants for them data error is loading and is error equals use query and our cache the item in cache that we're going to be refreshing later should be called books and to fetch them we're going to use the function called get all books it needs to be a function that returns a promise and can get the params from the use query this particular one doesn't need any params but we need to define it inside of the api module let's create it inside of the src folder create the api.js i like to abstract the data fetching functions so i'm not bound to specific implementation and my components don't know if i use some library like axios or i use the fetch api or induce something else doesn't matter i can easily change to something different so here with export a function get all books it's an async function async and inside of it we first get the response equals await fetch and then we need to use the url i could use it directly here and say http localhost 4000 because my server is running on port 4000 and then books but to make it easier to configure your app and later use on in production if you want to it's better to have a dot n file which will store our configuration items let's create a new file in the root of your project along with git ignore packet json and so on create new file call it dot n and create react app supports the dot n files by default you need to prefix all the properties there with react app so for example if we want to create a property called api server then it's going to be called react app api server and here we'll store the url http localhost and port 4000. now we can use this property this attribute inside of the api module instead of using it directly here we remove everything up until the slash we switch to template string and here we use a placeholder and we get the value from the process and react app api server good okay now we have the response from the server but we need to parse it as a json but before we do it we need to check if the response was 200 if it had the status 200 which means that it was performed successfully to do this we can actually check the ok flag on the response we do it like this if not response awk then we throw a new error and we say something went wrong otherwise if everything is okay we return response dot json it's a function that transforms the response value which is a string to adjacent because we expect a json response from our server now let's get back to the book list and import the get all books function import get all books from api now we can work on our layout for example we know that if the status is loading then we need to show the pre-loader the spinner and we do it by making an early return we check if is loading then we return a special layout for this case i'm going to reuse the container import container from shared container it's going to be a wrapper container inside of it we use a flex container we need to import it from the rebus import flex from rebas style components and then we have the closing flex and inside of this flex block we'll have our loader it's going to be an animated spinner and we import it import loader from react loader spinner the loader should have the type three dots color it should be a light gray color i'm going to use ccc and the height should be 30. and let's close it now the flex should have padding vertical py 5 and justify content should be center format the document and we have the loading state that's good now we need to process the error if something goes wrong if is error then we return and let's just return the message for now just a span which will say error and then error message now if it's not loading and not error then we return the regular layout which is a list of books we're going to use the component again to wrap everything container inside of it we have a flex with flex direction column because we want to position the items vertically and align items should be center here we're going to map through the data it's going to be an array that we're getting from the server you can verify it in the swagger documentation you see we get an array of items so we use data map and for each of the items we get author which is spelled differently a title and an id as you can see each of them has an author a title and an id field then we return i'm using um round brackets to not use the return statement this way i can just state that it should be a for now let's use a div and then we'll create a separate component each div here should have a key because we're iterating through the array and the react requires you to use the key so it knows which element is which so the key should be id and then inside of it we're gonna say author dash title and for now it's okay i guess let's make sure that we're running our client go to the browser reload the page go to the root and something is wrong let's see what did we get from the server if we open network reload the page we got books 304 and the response was whoa we've used the wrong server address let's go to amph localhost 4000 okay should be correct but here i'm using 3000 maybe i should relaunch the app okay and now we don't get any response because the server is not running let's open the server in another tab cd workspace react query crowd 3 cd server yarn start i didn't reload the page and react query re-fetched the data automatically that's one of the cool things about it by default it tries to refresh the data whenever you leave the the window when you leave that tab and get back to it let's close the console okay we have all our books rendered but we want them to look nicer so let's define a book item component for them go back to the app inside of the book list page we create another component new file book item dot jsx and now i'm not going to re-export it from the index so it's going to be a bit harder to use it in other components let's define the book item here export const book item equals a function for now let's return null and we need a bunch of inputs import flex text button and the link as styled link just like we did for the nav bar because we are going to be using the link from direct router dom as well we import them from rebas styled components then we import the link import link from react router dom now instead of null let's return a flex inside of which we're going to render a text that will say the author name which we'll get from the props author along with the title and the id let's add a link the component should be styled link just like in navbar component equals styled link that too should be a template string update book is going to lead us to the book editing page update book and this page needs an id by the way did we implement this route no we didn't do it completely so if you need to work with segments so you pass some data in the url segment like we want to do here you can use the column id and this id will be accessible inside of that update book page through the hooks provided through react router dom so now it should be okay let's go back to the book item and now we can have another part of the url here which will be the id of the book and the text of the link will be the title the title of the book we also add the margin right which should be auto let's format the document add a button and this button is not going to do anything for now it's just going to say remove we're going to implement this a little bit later and before we move on let's add the padding 3 with 100 and align items center that should do it for now let's go back to the books list import the book item from the book ira module and now instead of the div we're going to be using our book item component book item author author title title key id and we also need to pass the id and we pass the id as an id prop and we close the tag all right let's go to the browser everything looks okay i would say the button needs a little bit of left margin let's go let's go back book item button ml equals five and now we should be okay yeah looks fine now so we have a list of the books and we potentially would like to remove them if we click the remove button now nothing happens and we could do it using the mutations so in react query queries are a way to fetch the data and mutations are the way to update the data on the backend let's go back to the app and inside of the book item we're going to import the use mutation and the use query client from react query now we can define the mutation function we're going to be using mutate async mutate async that's one of the ways to use the mutation function if you go to the docs and check out the api reference for the use mutation you will see that we get a bunch of values here we get the data as well if the fetching function will actually return the value from the server the error the flags if we got an error if it's loading or idle or paused the difference is that the idle state is before we fetch that is loading is when we are in the process of fetching and disposed if we post the mutation and we also get two mutate and we data sync functions mutate is a synchronous function the mutate function is synchronous and if you need to do something after you've mutated your values you will need to use the unsuccess handle which you can pass to use mutation inside of the options object in our case we'll want to refresh the books cache after we successfully remove the book or perform the mutation so it's easier to do it or at least for me i like it more using the mutate async function which will allow us to perform this function using the async await syntax and after we do it clean up the cache let's do it now so we get them mutate async and we'll also need to get the ease loading status and we get them from the use mutation you need to pass the emulator function to it and in our case it's going to be the remove book function that will also define in the api.js inside of the api.js module export new constant called remove book which is in a sync function that receives an id and then it gets the response using the await fetch here we use the environment property again process and react app api server slash books slash id the one that we got from the arguments and then we need to pass an options object to the fetch function the only option we need to pass here is the method the http method and it's delete after it's done we can check if not response walk then we throw new error with the message from response json message because i expect that in this case the server will return the object with an error that will have a message field and if everything is fine we just return true we don't need any data now let's get back to the book item import remove book from the api module now let's define the removal function const remove equals an sync function where we'll await for the mutated sync to perform mutate async we pass an id here we get the id from the props so the component the book item component is aware of its id and then we need to clear the cache or invalidate queries for the cache item books let's get the query client const query client equals use query client without the extra t and then we call query client invalidate queries and we invalidate the books because inside of the book list we are using the books query so after we call the invalidate queries for the books the cache will be cleaned up and it will force the books list to re-fetch the data now that we have the remove function we can use it as a non-click handler on our button on click remove you probably wonder why do we need the ease loading flag we need it to show the loading spinner when we click the remove and it didn't happen so the server i'm using for this app is intentionally slow it has a delay of one second for each of the responses you might have noticed it when we were using the swagger documentation to check the routes so instead of just remove we're going to have a javascript expression here and if we are loading then we return a loader which we get from the react loader spinner library import loader from react loader spinner and it should be three dots as well three dots color should be white fff and height should be 10 and we close this stack otherwise if we are not loading it should actually say remove and we are good let's go to the documentation and let's actually create a new book we already have the test test here and we can execute it again you see there was a one second delay we got the new book if we go to the app it was loaded automatically we can click remove and it was removed now the two screens that are left are to create new books and update them and both of them are going to use the same form so let's start with this form first as is going to be used by two pages i'm going to put it inside of that shared folder create a new file and call it book form.jsx here we'll need just a couple of components from the rebus library so we import the box and the button from it from rebas styled components we'll also need the label and the input but they are in another library called rebus forms style components so we import label input those are styled versions of the regular label and input elements from at rebus forms and then we import the use form because i'm going to be using react cook form to make it easier to work with the book form that we're having here it's a hook from react hook form and we also need the loader because the server is work is working quite slow but that's intentional import loader from react loader spinner now let's export our component expert const book form equals a function that will receive the default values the idea is that the book form is going to be used both on the update book page and create book page of course for the creation of the new book you don't need the default values the inputs can be empty and it's fine but when you update the book you will need the default values and to abstract this knowledge this responsibility from the book form itself we create a prop default values which we can pass from the page that is responsible for updating or creating the book in our case updating so the default values and also the on form submit function and also we need the is loading flag the thing is as we abstract the actual book creation or updating to the page the query or mutation that we'll use there will be providing us with the is loading flag and we can show it on the submit button but we need to get this is loading value and we pass it through the props so we define a function we'll use react hook form so we get the register and handle submit from it handle submit from equals use form and we pass the default values there if the default values will be undefined the form will be just empty the initial state will be empty for it now we define the onsubmit function on submit equals handle submit the function from the react hook form and here we pass a callback which will get the data this is where react form comes very handy we just get the data from the form and as the data will already be in the format that we expect the input names will match the names of the fields in the expected object we can just pass it to the on form submit function confirm submit and we pass the data to it that's it now let's define the layout return of course it needs to be a form and as a non-submit handler we pass our own submit function now inside of it we render the box and this box will be a container for the label and an input so we specify the style as x equals margin bottom three inside of the box we use the label which will say title and the html4 field for this label should be title because that's going to be the id of our input and then we define the input we pass the ref register it's needed because the reactor form library uses the references to the actual dom elements to be able to control them and that's what we are doing here we pass the register to all the inputs that we are going to be using in this form ref register id equals title name also equals title this field is going to affect the name of the field inside of the data object and we need it to be title and the type is going to be text now we can copy this box for another input that is going to be called author it should say author as well the ref should be registered the id should be author and the name should be author and the type should be text it's fine and finally we have a button to submit this form button let's say the closing tag this button will check if we're loading basically the same way as the removal button is going to check if is loading if it's loading then we use the loader actually it's a good idea to create another component that would incorporate this logic and maybe it's a good homework for you if you're going to repeat the actions in this video so we use the loader with type 3 dots and color fff and height 10. as you can see it's exactly the same values as in previous button that was removing items otherwise it should say submit okay let's fix the typos and close the tag format the document all right the form is ready but it's not gonna do anything on its own we need to use it now inside of the book updation page let's start with the update book and go to update book component let's export a new component export const update book equals a function for now return null let's go back to the app make sure that we've imported the update book component that's good and this page is responsible for updating the value so it's going to contain both the query and the mutation so it's an interesting case so first of all we need to get the id and as you remember inside of the app.js we have this segment here so react router dom allows us to get this part of the segment which in our case is called id by using the use params hook so we define an id constant and we use the destructuring assignment here because we're going to get an object that will also in our case there are not going to be others but there will be this id param use params and we need to import them from the reactor order dom import use params from react router dom we'll also need to have the history because after we update the book we want to navigate back to the index where we have the list of all the books so we get the history equals use history that's another hook from react router dom use history after we have it we can start about thinking how do we fetch the data about the book because we need the default values let's define the const that will have the data error is loading status and is error we get it using the use query we've already used this hook on the index page use query book that's the name of the cache and we pass an id the object with an id to our function that will fetch the book information and then as a second argument we pass the get book function so here is the difference between the books list where we pass only the string because we didn't need any additional params and in the update book use query we pass an array that's another possible syntax you can pass the cache name it should be burst the key and then you can pass the object with the additional params in our case we only need to pass the id to the getbook function by the way let's go to the api and define this function export const getbook equals and async function that gets the query key which in our case is going to be an array and we're going to destructure it by doing like this const underscore key i'm using an underscore here to signify that we're not going to use it it's going to be an unused variable so we also need to specify a special comment for eslin so it doesn't create a warning yes lint disable no unused vars and we close the comment next value was an object with a field id equals weary key so we destructure the query key we get the key itself which is the book the string book but we are not going to use it and we get the id which we are going to use then we get the response the response we get using the await fetch here we use a template string we use the process and react app api server we pass in the books url and then we also pass the id which we got from the query key we don't need to provide any additional options because that's the default get request we are getting the data from the server after we have the response we can check if it's okay or rather if it's not ok if not response ok then we throw new error where we pass the response json message as a value if everything is fine we just return response json by the way as you can see the code for handling the errors or passing down the json is going to be very similar for almost all the functions here so maybe it's a good idea to think how could we implement a wrapping function or some sort of decorator to be able to not repeat ourselves and keep our code dry that might be another homework for this video or maybe i will record another video about it myself after we have this function let's go back to the update book page and import it get book from api now we need to handle the is loading state if is loading and here i'm gonna just reuse the same code that we used in the books list i'm gonna just copy it from there and actually it's a good sign that we need the whole layout for the loader that is gonna be centered properly and have a proper settings update book and let's use it here form the document and don't forget to return your layout now if something is wrong and we get an error let's have another check here is error then we do almost the same but instead of the loader we're going to show error and then we render the error message and if it's not loading and it's not error we don't have the error from the server then we return the following layout we return a container with a box inside of it this box has an additional style property here we need to have a vertical padding 3 and then it has a heading it is just a text heading some big text with style margin bottom 3 and a closing tag and this heading is going to be saying update book we don't add this heading to the shared form because we're also going to be using this form on the create book page so the heading belongs to the page itself not the form and then we use the book form default values is data we got it from the use query this one let's close the tag we also need to pass the on form submit and we need to define a function for it let's do it now before all the checks we define a constant on form submit it's going to be an async function that will receive the data and it needs to send it to the backend to be able to send the data to the backend we have the mutations so let's define one const mutate i think you should be already familiar with it because we've used it to remove the books in the book item component here we'll also need the is loading state but here's the problem we already have the is loading flag from the use query i think good idea here would be to rename it is loading will be called is mutating and then we call use mutation and we pass the update book function to it and let's add the missing imports we need to import the use query use mutation from react query we need to import the visual elements the box the heading and the flex container from rebus style components and we also need to import the book form and the container from the shared components to be able to import both of them like this from the shared i'm going to add an index file to the shared folder index.js and then i'm going to export everything from container export everything from book form and actually export everything from navbar so now we'll be able to just say export those modules from the shirt and we don't need to specify that the book form comes from the book form module we can just say that they are stored in the shared folder all right we have the imports but we don't have the update book function first we need to define it in the api module let's export a new constant called update book it's in a sync function that will get the data its id and all other fields so we spread it press the object we get the id field separately and everything else is in the data object it's a function we get the response await fetch we fetch the process and react app api server books id this is why we destructured this object to get the id first and then we need to pass an options object it needs to contain the method in our case it's put because we're updating the data not creating the new entity then we have the headers content type application json this way we tell the server that we're going to send the json and then the body is going to be json ringify data we transform the object into a string ringified now if the response is not okay response not awk then we we throw new error and we pass the response json message to it otherwise we return response json let's go to the update book page and from the api also import the update book function after we did it inside of the on form submit function we can await mutate async and this will actually perform the update book we pass the object with data that we got from the form but it won't contain the id so we get the id from the params and after we do it we call the history push and we navigate to the root now we need to pass the onform submit to our book form onformsubmit equals on form submit and we also need to pass the is loading state so until the mutation is really done we want to share the pre-loader in our form and it supports this functionality so let's pass the is mutating form of the document and it should be fine one thing that we forgot to import is a loader import loader from react loader spinner okay let's try it out if we click on one of those books for example programming perls and then we add i don't know something to the author name submit we go back and the author is updated let's fix it back and we remove this submit we get a nice loader on the bottom and everything is fine the only functionality that is left is to be able to create the new books okay let's define this component go to create book folder create book file and let's import a bunch of things first of all we'll need the book form import book form and also a container component i'm going to import it now just because it's convenient we're importing them both from the shared from shared speaking of components we'll also need the box and the heading from rebas style components okay so in this page create book we only need to use the mutation in the update book page we needed both the default values so we used the query to create the data and here we need only to mutate the data we need to create the book from scratch so let's define it const mutate async and is loading use mutation blips bloops and we need to use the create book function from the api that doesn't exist there yet so let's import the use mutation import use mutation from react query and let's define the create book function inside of the api module let's export expert const create book equals async the only thing that we need here is data and it's a function where we get the response using await fetch we use the process and we get the environment variable called react app api server books and just slash we don't need to pass any sort of id we don't know it yet we're just gonna create a new book then we specify the options object the method is post because we are creating a new entity the headers is an object with a field content type application and json because we tell the server that we're gonna send the json body and then the body is json stringify data just like we did when we updated the book now we check if response is not okay and then we throw a new error response json message maybe it would make a good video if i would refactor this part and create some reusable piece of code that we would implement in that vid and if everything is fine we return a response json now that we have our create book function we can go back to createbook component import the create book from api format the document and now we can return a layout we use container to wrap the whole page inside of this container we use a box with some additional padding 6 equals padding y vertical padding three and inside of this box we're under a heading that will say create new book so we can immediately see what are we gonna do with the book here update or create and then we pass a book form on form submit we need to define this function constant form submit equals a function which is async by the way because we're going to use the data sync there it's a function where we call the await mutate and sync and we pass the data after we do it we need to navigate back to the root so we'll need the history object const history equals use history did we import it no we did not let's import use history from react router dom okay we have the history now after we successfully mutated we've created the book we can navigate back to the root history push root now we can pass this on form submit as a prop to our book form on form submit and there is loading which we didn't have to rename to is mutating as an is loading prop is loading let's add some additional styles to the heading s6 equals margin bottom three and format the document i'm using the data here but i'm not getting it anywhere i forgot to use it in the in the arguments so we get it from the arguments from the book form pass it to the mutate async function and then we get to the root let's try test test test book book author maxim submit ok now we have it here now we can remove it and that means that we are done our app is working we have an app with a list of books where we can create new books google app and the author enabled up submit we have pre-loaders on every action we can edit the book with the default values and then we change them to something else submit we can remove the books and that means we have a complete crowd application create read update delete thank you for watching all the related materials for this video the server the client code all the examples are in the video description if you have any questions then leave them in the comments or you can join my discrete server and we can discuss this tutorial there also i have a small announcement i had an idea that video tutorials and articles are great at teaching but they don't provide the necessary practice you can repeat after the author and maybe give your own twist to the apps but what if there would be some resource where you could get an assignment and do it in your on your own on your own completely and then there are two options maybe you get a feedback or maybe you just make sure that all the tests pass so for the first assignment i just wrote some tests that automatically check that your solution works the link will also be in the description and i'm going to try to make it a newsletter so if you follow that link you will see the first issue of this newsletter and i think somewhere on the screen will be a subscribe button as well so if you want to get more newsletters like this you can subscribe anyway if you check out the first newsletter the first letter it's actually not even a letter it's a webpage and you like the idea or you have any ideas on how to improve it then reach out to me in discord or if you know my or through email and let's talk about it okay see you next time and let's keep in touch
Info
Channel: Maksim Ivanov
Views: 22,463
Rating: undefined out of 5
Keywords:
Id: 4UCwA2n4gsA
Channel Id: undefined
Length: 56min 59sec (3419 seconds)
Published: Sun Jan 03 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.