{"id":19109276,"url":"https://github.com/obrm/react-router-exercise","last_synced_at":"2026-06-17T06:31:19.179Z","repository":{"id":194554191,"uuid":"690595385","full_name":"obrm/react-router-exercise","owner":"obrm","description":null,"archived":false,"fork":false,"pushed_at":"2023-09-19T09:24:48.000Z","size":171,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-03T03:42:14.677Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/obrm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-09-12T13:50:10.000Z","updated_at":"2023-09-12T13:50:18.000Z","dependencies_parsed_at":"2024-11-09T04:20:22.535Z","dependency_job_id":"ca18c874-5f95-4890-81b2-aa2dfeb72627","html_url":"https://github.com/obrm/react-router-exercise","commit_stats":null,"previous_names":["obrm/react-router-exercise"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/obrm%2Freact-router-exercise","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/obrm%2Freact-router-exercise/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/obrm%2Freact-router-exercise/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/obrm%2Freact-router-exercise/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/obrm","download_url":"https://codeload.github.com/obrm/react-router-exercise/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240163601,"owners_count":19758032,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T04:19:46.989Z","updated_at":"2026-05-31T05:30:15.138Z","avatar_url":"https://github.com/obrm.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# React Router Exercise: Building a Product Management System\n\nWelcome to our React Router exercises! In this set of exercises, you'll learn how to build a basic product management system using React Router. You'll start by setting up the routing system in the main app component, then move on to constructing shared layout components, protected routes, and child components like product details and add/edit forms. Along the way, you'll also learn how to integrate authentication and handle undefined routes. Finally, you'll enhance several existing components with features related to React Router. These exercises aim to provide hands-on experience with React Router, helping you understand how it works and apply these concepts in practical scenarios. Let's get started!\n\n\n## Evaluation and Testing\n\n**Objective**: This section is dedicated to ensuring that all the functionalities you've implemented throughout the exercise are working correctly. Periodically evaluating and testing your work is crucial in a real-world development setting, helping you to catch and address issues before they become bigger problems.\n\n### Instructions:\n\n1. **Checking Console for Errors**: \n   - Always ensure there are no errors in the browser console. This is often the first indicator of any issues in your code.\n   \n2. **Navigation and Route Validation**:\n   - Navigate through every route you've set up in the application. Make sure that each route loads the expected component and handles edge cases (like undefined routes) appropriately.\n   \n3. **SharedLayout Consistency**:\n   - As you navigate through the application, verify that the shared layout elements like the header, navigation, and footer remain consistent across different pages.\n   \n4. **Protected Routes**:\n   - Try accessing protected routes without authentication by passing the user prop ass null. You should be redirected to the home page, signaling unauthenticated users are appropriately blocked.\n   - After authentication, ensure you can access these routes without any issues.\n\n5. **Functionality of the `Product`, `AddProduct`, and `EditProduct` Components**:\n   - For the `Product` component, check that it displays the right details for each product ID.\n   - When adding a product using the `AddProduct` component, ensure that the product gets added and that you're navigated to the desired page afterward.\n   - The `EditProduct` component should accurately fetch and display product details based on the URL's product ID. After editing, ensure the changes are saved and that navigation occurs as expected.\n\nRemember, the objective is not just about building features but ensuring they work seamlessly and efficiently. Regular evaluation helps maintain the quality and reliability of your application. In the real world, these evaluations often lead to iterations where improvements and bug fixes are made.\n\n\n\n## Section 1: Configuring the App.jsx Component\n\n**Objective**: The goal of this section is to guide you through the process of building the primary `App` component for the web application. This component will establish the necessary routing system to navigate through the various parts of the application.\n\n### Instructions:\n\n1. **Defining the Routing System**:\n    - Begin by defining the `routes` array. This array will store objects that dictate how navigation within your application operates.\n    - Each route object should define a `path` that represents a URL segment and an `element` which specifies what component should be rendered when that path is accessed.\n    - You can nest routes by including a `children` property in a route object. Nested routes are useful when a part of your application has a shared layout across multiple sub-pages.\n\n2. **Setting up the Base Route**:\n    - Create the first object in the `routes` array. This object should represent the root path, `'/'`.\n    - For this route, use the `SharedLayout` component as the `element`. Pass the `user` data to it as a prop.\n    - As this route has several child routes (like Home, AddProduct, etc.), you will need to set up a `children` property that is an array of these child route objects.\n\n3. **Configuring Child Routes**:\n    - Set up the `index` route that represents the default child of the root path. This route should render the `Home` component and receives the `products` data as props.\n    - Create another child route for adding a product. This path should be 'add' and it should use the `ProtectedRoute` component wrapping the `AddProduct` component. Pass the `user` prop to `ProtectedRoute`.\n    - Next, configure a nested route for products. It should be an object and the path should be 'products' and it should further have child routes for specific product details and editing a product. Use the dynamic `:productId` in the path to cater for any product ID.\n        - For viewing a specific product, render the `Product` component with access to the `products` data.\n        - For editing a product, use the `ProtectedRoute` wrapping the `EditProduct` component. Again, ensure the `ProtectedRoute` receives the `user` prop.\n    \n4. **Handling Undefined Routes**:\n    - To ensure user-friendly behavior, set up routes to handle undefined or erroneous paths:\n        - As a catch-all for any undefined paths, add a route with the path `'*'` and have it render the `NotFound` component.\n\n5. **Implementing the Router**:\n    - Now that your `routes` array is defined, create a browser router using the `createBrowserRouter` function and passing the `routes` array to it.\n    - Return the `RouterProvider` component. This provider requires a `router` prop which should receive the browser router you just created.\n  \n    ```jsx\n    const App = () =\u003e {\n        const router = createBrowserRouter(routes);\n\n        return (\n            \u003cRouterProvider router={router} /\u003e    \n        );\n    };\n    ```\n\n### Hints:\n- The `ProtectedRoute` component is specially designed to restrict access to certain routes based on user authentication. It's essential to wrap components like `AddProduct` and `EditProduct` in this component to prevent unauthorized access.\n- Using dynamic segments like `:productId` in your paths enables React Router to extract parameters from the URL, which can be later used to fetch specific data or perform certain actions.\n\n## Section 2: Constructing the SharedLayout Component\n\n**Objective**: In this section, you will create the `SharedLayout` component. This component will act as a shell for other components, ensuring consistent elements such as the header, navigation, and footer are present across multiple pages of your web application.\n\n### Instructions:\n\n1. **Initializing the Component**:\n    - The necessary imports are given: `Outlet`, and `NavLink`.\n    - Next, define the `SharedLayout` functional component that takes `user` as a prop.\n\n2. **Structuring the Layout**:\n    - Inside the component's return statement, commence by embedding a `div` element with a class of `container`. This div will serve as the main container for our layout elements.\n\n3. **Constructing the Navigation**:\n    - Begin by adding a navigation link for the homepage: use a list item (`li`) encapsulating a `NavLink` component. This component, stemming from `react-router-dom`, will navigate users to the root path (`/`). To make the active link more distinguishable, utilize a callback function for its `className` prop to conditionally assign the class 'active'.\n    \n    ```jsx\n    \u003cli\u003e\n        \u003cNavLink\n            to=\"/\"\n            className={({ isActive }) =\u003e isActive ? 'active' : undefined}\u003e\n            Home\n        \u003c/NavLink\u003e\n    \u003c/li\u003e     \n    ```\n\n    - Display an additional option allowing them to add a product. Again, wrap a `NavLink` component inside a list item (`li`). This link should navigate users to `/add`, and also make use of the conditional class assignment.\n\n5. **Configuring the Main Content Rendering Area**:\n    - Below the navigation, you should structure the main content area using a `main` tag.\n    - The main content area is particularly special: it dynamically displays content based on the currently active route. To facilitate this, insert the `Outlet` component from `react-router-dom` inside the `main` section. Think of the `Outlet` as a dynamic placeholder; it changes the rendered component according to the path.\n\n\n## Section 3: Creating the ProtectedRoute Component\n\n**Objective**: This section will guide you through creating a `ProtectedRoute` component, which ensures that certain routes are only accessible to authenticated users. You'll be utilizing the `useNavigate` hook from `react-router-dom` for navigation within this component.\n\n### Instructions:\n\n1. **Using the `useNavigate` Hook**:\n    - Inside the `ProtectedRoute` component, initialize a variable called `navigate` using the `useNavigate` hook. This hook provides a function for programmatic navigation.\n\n2. **Checking Authentication**:\n    - In the component, implement a conditional check inside a `useEffect` hook to determine if the `user` is authenticated. You can do this by checking if `user` exists. Don't forget to pass to the `useEffect` hook dependencies array the required dependencies.\n\n    ```jsx\n     useEffect(() =\u003e {\n        if (!user) {\n            navigate(\"/\");\n        }    \n    }, [navigate, user]);\n    ```\n\n    - If the user is not authenticated (i.e., `!user`), you want to redirect them to an appropriate page. In this example, it assumes a route `'/'` as the redirect destination. \n\n3. **Redirecting Unauthenticated Users**:\n    - To redirect users when they are not authenticated, use the `navigate` function with the appropriate route (e.g., `navigate('/')`). This will take them to the designated destination route.\n\n4. **Rendering Child Components for Authenticated Users**:\n    - If the user is authenticated, you want to render the child components. Return `children` within curly braces `{children}`. This allows the children components passed to `ProtectedRoute` to be rendered when the user is authenticated.\n\n## Section 4: Building the `Product` Component\n\n**Objective**: In this section, we'll develop a `Product` component that will display detailed information about a product based on its ID from the URL. We'll make use of the `Link` and `useParams` hooks from `react-router-dom` to achieve this.\n\n### Instructions:\n\n1. **Extracting Product ID from the URL**:\n    - Within the `Product` component, initialize a constant named `productId` by destructuring it from the `useParams()` hook. This hook extracts parameters from the current route, and in our case, we're interested in the product's ID.\n\n2. **Identifying the Relevant Product**:\n    - With the `productId` at hand, our next step is to identify the corresponding product from the `products` prop.\n    - Declare a constant called `product` and set it to the result of the `find` method on the `products` array.\n    - The `find` method's callback should compare the `id` of each product to the `productId`. Remember to convert `productId` to an integer using `parseInt` since parameters fetched using `useParams` are strings by default.\n\n3. **Handling Product Absence**:\n    - Considering that the product may not always exist (e.g., if an incorrect ID is manually input into the URL), we need to handle such scenarios gracefully.\n    - Implement a conditional check: If the `product` constant is undefined, return a `div` element with the text \"Product not found!\".\n\n4. **Facilitating Product Edits**:\n    - Equip users with the capability to modify the product details.\n    - Implement the `Link` component from `react-router-dom` to navigate to the product's edit page.\n    - Set the `to` prop of the `Link` component to a dynamic value: `/products/${productId}/edit`.\n    - Give the `edit-link` class to this link for styling and label the link \"Edit Product\".\n\n\n## Section 5: Building the `AddProduct` Component with Navigation\n\n**Objective**: The purpose of this section is to guide you through enhancing the `AddProduct` component by adding navigation capabilities. This ensures that after a product is added, the user is navigated back to the home page or another appropriate page.\n\n### Instructions:\n\n1. **Setting Up Navigation**:\n    - Invoke the `useNavigate` hook and assign the returned function to a constant named `navigate`. This function will be used to programmatically navigate the user.\n\n2. **Constructing the `handleSubmit` Function with Navigation**:   \n    - After logging the product and resetting the state, employ the `navigate` function with `'/'` as its argument. This action will redirect the user to the home page after they've added a product.\n\n\n## Section 6: Enhancing the `EditProduct` Component with React Router\n\n**Objective**: The purpose of this section is to enhance the `EditProduct` component by integrating functionalities associated with React Router. By the end, you'll have a component that fetches the product to edit based on the ID from the URL and navigates back to the home page after the editing is done.\n\n### Instructions:\n\n1. **Retrieving the Product ID from the URL**:\n    - Using the `useParams` hook from `react-router-dom`, extract the `productId` parameter from the current URL. \n    \n\n2. **Setting Up Programmatic Navigation**:\n    - Invoke the `useNavigate` hook from `react-router-dom` and assign the returned function to a constant named `navigate`. This function will allow you to programmatically redirect users after the product edits have been saved.\n\n3. **Fetching the Product Data Based on URL Parameter**:\n    - With the `productId` extracted in step 1, search for the corresponding product within the `products` mock data. Ensure you parse the `productId` to an integer for accurate comparison.\n\n4. **Initializing the Form Data with the Fetched Product's Information**:\n    - Set the initial state of the `formData` using the `useState` hook. Populate it with the properties of the found product (i.e., `name`, `description`, `price`, and `stock`).\n    ```javascript\n    const [formData, setFormData] = useState({\n        name: product.name,\n        description: product.description,\n        price: product.price,\n        stock: product.stock,\n    });\n    ```\n\n5. **Enhancing the `handleSubmit` Function with Navigation**:\n    - After handling the form's submit action (like saving edits), employ the `navigate` function with `'/'` as its argument. This step will ensure the user gets redirected to the home page after the edits have been submitted.\n    ```javascript\n    const handleSubmit = (e) =\u003e {\n        e.preventDefault();\n        navigate(`/`);\n    };\n    ```\n## Conclusion\n\nCongratulations on completing this comprehensive React Router tutorial! Throughout this exercise, you learned how to build an effective routing solution using React Router. You covered topics ranging from configuring base routes, constructing child routes, handling undefined routes, setting up protected routes, implementing react router, building layout components, working with Link components, and much more. These skills will undoubtedly help you in your career as a developer and enable you to build robust, modern web applications that meet today's demands. ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fobrm%2Freact-router-exercise","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fobrm%2Freact-router-exercise","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fobrm%2Freact-router-exercise/lists"}