This app was created with Create React App. Create React App took care of the behind-the-scenes stuff, and I was able to focus on fun stuff like building components and writing the JSX and JavaScript that handles the app's functionality. The styles are all either hard coded or imported from React Bootstrap.
This app has been deployed at https://sweet-zuccutto-773929.netlify.app/. Alternatively, if you want to run it locally you can clone the repo and run npm install
and npm start
. The backend is a mock json-server which has been deployed to Heroku (here if you want to see the data we're working with), so no local json-server is necessary to run the app.
Much of the functionality is similar to my first Book Wyrm app, but with the help of React and React Bootstrap, I was able to improve on a few things, not least of which was the styling. I used React Router to split some of the app's functionality into different pages and to add a few more features (such as a home page, the featured book page, etc). Here's a brief summary of the app's features. The app opens to the home page, which displays a nav bar and an introductory message. The featured book tab navigates to a static page that displays a featured book with an "official" Book Wyrms review. The last tab, Contact, is also static and displays some basic information about the Chief Book Wyrm (me). The Search tab navigates to a search bar where books can be searched by title or author and displayed on pages of five books each, navigated with page buttons (shoutout to React Bootstrap for making those much cleaner and easier to create than last time!), clicking on the button in each book card displays a more detailed version of the book on the left side of the window, including any relevant Book Wyrms information (ratings, reviews, etc).
Note: Due to the somewhat disorganized nature of the Open Library API, selecting a book with no cover image will throw an error. I know what's causing the bug and I hope to get to it one day
The Shelf tab will redirect the user to a login page if they are not already logged in. Once logged in, the Shelf tab will display a read list, and a set of buttons to toggle to the wish list and back. Each book on the lists will have a button to display a more detailed version of the book (like on the search page). The book cards on the read list will also display the user's rating or review if applicable, as well as buttons to change the rating or edit/delete the review.
On load, an array
of users is fetched via the useEffect
hook and saved to state in order to validate login attempts and to prevent a new account from selecting a username that is already taken. The two top-level components are Header
and Body
. the Header
component is static, other than the login/sign up buttons switching to a logout button once a user is logged in. The Body
component is handled by React router, with the NavBar
component in the Header
providing links to navigate between the different routes. The Home
component is simple, it just renders JSX to the page. The FeaturedBook
and Contact
components are static in the sense that they don't change when interacted with by the user, but they use state to populate the component with data fetched from the backend. The Search
component initially fetches data from the Open Library API and uses it (after being sifted through by the code to try to eliminate inconsistencies and other issues) to render the search results. When a book is selected, a GET
is sent to the Book Wyrms backend to check if the book exists in the database. If it does, the detailed book is rendered to the page from there. If not, a POST
is sent to add the book to the database, and the book is rendered with the data returned in the response. In the Shelf
component, the information is all rendered from the Book Wyrm database. When a book is marked read, added to a wish list, or any other user-specific action, both the book information and user information is updated and re-rendered. To simplify this process, the currentUser
and currentBook
state variables, as well as their setter functions, are globally accessible with the useContext
hook. This allows for each of these objects to be modified in response to user actions, sent to the backend via a PATCH
request, with the response passed to the setter function to set state and re-render the component to reflect the updated information. This also allows the state variables to be modified destructively, as they themselves are not being passed to the setter functions, rather they are sent to the server and the response is.
That's it for my first React application! Any questions? Feel free to email me or connect with me on LinkedIn. Thanks for checking it out!
All the best, Naftali Kulik