Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Project reat homework w2 #26

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

christinaghazal
Copy link

No description provided.

@durw4rd durw4rd self-assigned this Dec 26, 2023
Copy link

@durw4rd durw4rd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello Christina, thank you for your work this week!

There are still a few things I'd like you to improve before I can approve your work.

The main one is the missing product detail page. I'm not sure if you forgot to commit some of your changes or if you didn't know how to approach this task? Either way is fine. If you simply forgot to upload your changes, please do so and let me know when I can review them. If you didn't know how to go about creating the product detail page, feel free to reach out on Slack and I'll can give you more detailed instructions.

At a high level:

  1. You will need to update the App.js file to complete the definition of the dedicated route - I have left a comment with an example there.
  2. You will need to create a React component that render to content of the product detail page according to the homework instructions. In this component, you can use the useParams hook to know what is the ID of the product that should be loaded from the API endpoint.
  3. Each of the product tiles on the homepage should lead to a corresponding product detail page. You will need to find a way of making the product ID available as a prop in the Product component. You can then use for example the useNavigate hook from the React Router Dom package to handle the navigation.

Secondly, I have added a few comments around the handling of the loading state of the CategoryList and ProductList components. The main idea is that the page should visually indicate when the app is waiting for the response from the API/server. This also applies when switching between the product categories.

Lastly, you can simplify your component structure when you move the contents of the ProductsBlock into your Home component and delete the ProductBlock component.

import ProductsBlock from "../components/Products/ProductsBlock";

const Home = () => {
return <ProductsBlock />;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to use the ProductsBlock component here. Instead, load the ProductList and CategoryList components directly here and move the content of the ProductBlock component into this file instead. This will help you keep the application structure more streamlined.

Comment on lines 5 to 22
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);

function fetchCategories() {
fetch("https://fakestoreapi.com/products/categories")
.then((res) => {
setLoading(true);
return res.json();
})
.then((data) => {
setLoading(false);
setCategories(data);
})
.catch((error) => {
setLoading(false);
setError("Can not fetch data!");
});
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This way, the loading state is never true. You can either initialize the loading variable with true value when declaring the useState hook: const [loading, setLoading] = useState(false); or call setLoading(true) at the beginning of the fetchCategories function. You can then remove line 11 as it's not necessary anymore.


const ProductList = ({ category }) => {
const [products, setProducts] = useState([]);
const [loading, setLoading] = useState(false);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar feedback to the CategoryList component - I recommend initializing the loading variable with a true value.

function fetchProducts(url) {
fetch(url)
.then((res) => {
setLoading(true);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If loading is initialized as true this line is not necessary.

}

useEffect(() => {
if (category) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To show the loading status also when users switch between the categories, set the loading variable to true at the beginning of this useEffect hook.


const router = createBrowserRouter([
{ path: "/", element: <Home /> },
{ path: "product:id" },
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might have forgotten to push some changes? I would expect here that the product/:id path will point to an element that will display the product detail page.

{ path: "/product/:id", element: <ProductDetails /> }

Copy link

@durw4rd durw4rd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Christina, great job on implementing the requested changes - I can see a great improvement in this version!
I will approve your work for this week but I still noticed that when running the app locally, I can see a list of warnings by the compiler. Some of the warnings are mostly cosmetic (i.e. the img alt warnings) but others can lead to your app behaving unexpectedly in some scenarios. I would like you to go through the list and see if you can resolve them all so the app compiles without any warnings before the next homework submission ;)

setError("Can not fetch data!");
});
setLoading(false);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the fetch function is asynchronous, you are ultimately setting the loading variable to false immediately, before any data has been fetched. Calling setLoading(false) inside the second then and catch blocks was correct.
To test if this works as desired, try opening the app in your browser while the throttling is enabled and check if the loading state is showing while the data is being fetched.

Comment on lines 10 to 28
const fetchProduct = async () => {
setLoading(true);
setError(null);
try {
const res = await fetch(`https://fakestoreapi.com/products/${id}`);
if (res.status !== 200) {
throw new Error("Something Went Wrong!");
}
const data = await res.json();
setProduct(data);
} catch (error) {
setError(error.message);
}
setLoading(false);
};

useEffect(function () {
fetchProduct();
}, []);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fetchProduct function has a dependency (id) so calling it inside the useEffect hook without including the dependency in the dependency array will cause a warning and can lead to issues later when it will i.e. be possible to navigate directly from one product detail page to another.
To solve this, I recommend moving the fetchProduct function inside the useEffect hook and adding id variable in the dependency array.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd recommend initializing the loading variable as true - similar to other components.

Copy link

@durw4rd durw4rd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
3 participants