首页
编程语言
数据库
网络开发
Algorithm算法
移动开发
系统相关
金融统计
人工智能
其他
首页
>
> 详细
讲解 program、Java编程设计辅导
Unlimited Att empts Allowed
Details
Points: 20 points
Overview
In this project, we will provide a centralized global store for our bookstore project. In projects 3 and
5, we used props to share data among components down the components hierarchy. However,
using props to share data is not ideal for large projects (remember prob drilling). In Project 6, we will
use Context in order to share data in our bookstore. We will also start working on a new component
called Cart for our bookstore project (will be fully implemented in Project 7). When fully
implemented, using this component, users can add any books that they want to buy to their cart,
view, modify (add quanti ty, remove, etc), and clear their cart.
Setup Your Server Project
Duplicate your server project [Name]BookstoreFetch on your machine, and name the new
project [Name]BookstoreState.
Open your new project in IntelliJ and find the setti ngs.gradle file. Update the project name to end
with State instead of Fetch. Then click the elephant to reload Gradle. Open your Tomcat run
configurati on, and go to the Deployment tab. Delete the war file asset that no longer works. Press
the Fix butt on, and change the applicati on context to /[Name]BookstoreState. Run the Tomcat
configurati on. The REST API should work as in Project 4. Test some complex APIs. For
example: htt p://localhost:8080/[Name]BookstoreFetch/api/categories/name/Classics/suggested?books?limit=2.
Project 6 - State Management
2024/7/3
20 Points Possible
In Progress
NEXT UP: Submit Assignment
Att empt 1 Add Comment
?
Project 6 - State Management
1/8
Ensure that React Developer tools for Chrome are installed (check here
(htt ps://react.dev/learn/react-developer-tools) for installati on)
Run the server project. Ensure that your Project 6 ([Name]BookstoreReactState) is working correctly
and running as expected.
Setup Your Client Project
Duplicate your client project [name]-bookostore-fetch-client on your machine, and name the new
project [name]-bookstore-state-client. Open the new project in VS Code or IntelliJ. Edit the
package.json file so that the name property is [name]-bookstore-state-client. Edit the vite.config.ts
file so that the base property is /[Name]BookstoreState. Finally, run the client project in the
terminal with "npm ci".
Run the client project. Ensure that it works like Project 5 running at
htt p://localhost:5173/[Name]BookstoreState.
Create Category Context
In P5, we fetched the category informati on from the backend in our App component and shared this
informati on with other components by using props. Below is the component hierarchy of our
bookstore. (Specifically, this is the component hierarchy of the AnotherBookstore starter code from
Project 3, so yours may differ slightly if you made modificati ons.)
?
Project 6 - State Management
2/8
The categories data, fetched in the App component, is used in components such as HeaderDropdown
and CategoryNav. Since these components are not direct children of the App component, the
categories data is first passed from App to AppHeader, and then to HeaderDropdown (similarly to
CategoryBookList to CategoryNav). Note that both AppHeader and CategoryBookList do not need
the category data directly themselves. This un-necessary passing through of properti es via
components is called "prop drilling". Prop drilling is a real problem if the component hierarchy is
deep.
React has a scheme that simplifies the sharing of data among components by creati ng a "global
store" called Context. Context hooks work by using Provider and Consumer components. Let's show
how we USE a context provider for categories first. We will then progressively create a "global store"
for category data.
In main.tsx, add the following bold import and code. Here we are showing intuiti vely that we can
make category informati on available to all child components inside the
without the need for
prop drilling.
import React from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import { CategoryProvider } from './contexts/CategoryContext';
?
Project 6 - State Management
3/8
import App from "./App.tsx";
import "./assets/global.css";
// import "./index.css";
ReactDOM.createRoot(document.getElementById("root")!).render(
);
Next we will show how to set up such a context and provider component. In your "client" module,
create a directory named contexts under the src directory. Create a file named CategoryContext.tsx
in that contexts folder. Create a context named Category by adding the following code. The code
uses createContext.
import React, { createContext, useState, useEffect, useContext } from 'react';
import { CategoryItem } from '../types';
import { fetchCategories } from '../services'; // This will be created later
// Define the type for the context value
interface CategoryContextType {
categories: CategoryItem[];
}
// Create the context with default values
const CategoryContext = createContext
(undefined);
Now it is ti me to add to CategoryContext.tsx to create a CategoryProvider component that fetches
the data from the backend using the REST API, updates the state, and makes it available for the
other components. Use the following skeleton code. Note that you have to REMOVE the code that
downloads and updates the categories state from the App component, since we will be fetching the
categories form the server here now.
// Create a provider component
export const CategoryProvider = ({ children }) => {
const [categories, setCategories] = useState
([]);
useEffect(() => {
fetchCategories()
.then((data) => setCategories(data))
.catch(console.error);
}, []); // Empty dependency array to run only once on page load
return (
{children} {/* This renders the nested components, e.g.,
*/}
);
};
// Create a custom hook for easy access to the context
export const useCategoryContext = () => {
const context = useContext(CategoryContext);
if (!context) {
throw new Error('useCategoryContext must be used within a CategoryProvider');
}
?
Project 6 - State Management
4/8
return context;
};
This creates a Provider called CategoryProvider that provides categories data to all its "children". The
CategoryProvider component receives a children prop. This prop is a special prop that React
automati cally passes to every component, representi ng the child components nested inside this
component. In JavaScript, ({ children }) is object destructuring syntax. It means we're extracti ng
the children property from the props object.
Now we have the categories data available to all components in our bookstore (descendants of the
App component). In order to use the context, we use the useContext() hook via the custom
useCategoryContext hook method above. Add the following statements in all the components that
need to use categories data.
import { useCategoryContext } from '../contexts/CategoryContext'; // Import the custom hook
...
const { categories } = useCategoryContext(); // Use the custom hook to get categories
return (
...
You can now delete all the occurrences of CategoryProps from the bookstore. Make sure category
data is not passed as props in any component. Replace the types.ts file with the one given at the
beginning of this page.
Finally, it is oft en a good idea to separate concerns. We are going to be making service calls to
retrieve data from our server, so let's create a services.ts file in the src folder as follows so we can
fetch categories and books. Move apiUrl from uti ls.ts to this file - it makes more sense here and no
longer needs to be exported.
import axios from 'axios';
import { CategoryItem } from './types';
const apiUrl =
`${location.protocol}//${location.hostname}:` +
`${location.port === '5173' ? '8080' : location.port}` +
`${import.meta.env.BASE_URL}/api`
export const fetchCategories = async (): Promise
=> {
const response = await axios.get(`${apiUrl}/categories`);
return response.data as CategoryItem[];
};
// add a method fetchBooksByCategoryName that takes a categoryName and requests book items
Run your client and make sure everything works exactly like P5.
Create Book Context?
The book data is passed from CategoryBookList to CategoryBookListItem as props in our bookstore
(AnotherBookstore) and that is the only place it is going to be used. There is no prop drilling problem
here as the two components are parent and child. Using props, instead of defining a Context in this
case is acceptable. However, if you prefer to use Context instead of props, you are free to do so as
this is a design decision.
?
Project 6 - State Management
5/8
Create the Cart
The last thing we are going to do for this project is to create a CartStore global store for a Shopping
Cart. Before doing this, we need to create a TypeScript class to represent items in our shopping cart
called ShoppingCartItem. Take a look at the given new types.ts file (above).
Our shopping cart (cart in short) will be a state just like the categories or the books states discussed
above. To manage the categories and the books states, we used the useState hook. These two states
are simple to manage as the only operati on they support is mutati ng the data. However, a cart
should support several different operati ons, such as adding and removing books from the cart,
incrementi ng/decrementi ng the quanti ty of a specific book in the cart, etc.
React has a hook, useReducer(), to manage such complex states. We are going to use the useReducer
hook to manage our cart state. The cart state will be used by multi ple components, such as in the
AppHeader to display the number of items in our cart, and in the CategoryBookListItem for "Add to
Cart" butt on to take effect. This warrants the creati on of a Context to make the cart a global stored
object.
Cart Step A: Create CartContext.tsx
1. Define Acti on Types:
Define acti on types for the reducer to handle different acti ons.
Define the acti ons ADD_BOOK , UPDATE_QUANTITY , and CLEAR_CART for the reducer.
import React, { createContext, useReducer, useContext, ReactNode } from 'react';
import { BookItem } from '../types';
import { ShoppingCart } from '../models/ShoppingCart';
// Define action types
type Action =
| { type: 'ADD_BOOK'; book: BookItem }
| { type: 'UPDATE_QUANTITY'; book: BookItem; quantity: number }
| { type: 'CLEAR_CART' };
// Define the initial state
const initialState: ShoppingCart = new ShoppingCart();
2. Create the Reducer:
Create a reducer functi on to manage the shopping cart state.
The reducer functi on, now named cartReducer , handles state transiti ons based on the acti on
type.
// Create the reducer function
const cartReducer = (state: ShoppingCart, action: Action): ShoppingCart => {
switch (action.type) {
case 'ADD_BOOK':
state.addBook(action.book);
return Object.assign(new ShoppingCart(), { ...state });
case 'UPDATE_QUANTITY':
// Pending code in next project...
case 'CLEAR_CART':
// Pending code in next project...
?
Project 6 - State Management
6/8
default:
return state;
}
};
3. Set Up Context and Provider:
Create the context and provider components with a properly initi alized state.
CartProvider uses useReducer to manage the shopping cart state and provides the cart and
dispatch to the context value.
// Create context
interface CartContextType {
cart: ShoppingCart;
dispatch: React.Dispatch
;
}
const CartContext = createContext
({ cart: initialState, dispatch: () => null
});
// Create provider component
export const CartProvider = ({ children }: { children: ReactNode }) => {
const [cart, dispatch] = useReducer(cartReducer, initialState);
return (
{children}
);
};
4. Create a Custom Hook:
Create a custom hook to easily access the shopping cart context.
useCart custom hook simplifies accessing the shopping cart context, ensuring it's used within
the provider.
// Create custom hook to use shopping cart context
export const useCart = () => {
const context = useContext(CartContext);
if (!context) {
throw new Error('useCart must be used within a CartProvider');
}
return context;
};
Cart Step B: Update the Project Component Structure
Note that the above context needs to provide two values, cart and dispatch, to consumer
components. Let us make it accessible to other components by putti ng it up in the components
hierarchy (refer to how we made the CategoryContext available by modifying the main.tsx file).
Cart Step C: Adding Books to the Cart
?
Project 6 - State Management
7/8
Now we have the cart and dispatch available to be used throughout the bookstore. Let's first use
dispatch in CategoryBookListItem component. Add the following code to the component.
import { useCart } from '../context/CartContext';
. . .
const { dispatch } = useCart();
const handleAddToCart = () => {
dispatch({ type: 'ADD_BOOK', book: props.book });
};
. . .
modify the "Add to Cart " butt on in the same component with the following onClick property:
. . .
Add to Cart
. . .
The above modificati ons allow the applicati on to respond to the click event on the "Add to Cart"
butt on by dispatching it to the CartReducer's reducer functi on and adding the book to the cart. Note
the content of the acti on object of the dispatch.
In your AppHeader component, use the cart to keep the cart count up to date. In order to get the
number of items in the cart you have to use the Cart context as shown above( useCart ). However,
we are interested in the cart value this ti me (not the dispatch). Once you have the cart data, you
have to get the number of items in the cart. Once you have the number of items, you update the
cart icon with the number of items. For AnotherBookstore it is like this (you should replace
expression with the correct javascript expression once you have the number of items:
{ expression }
Once you have done this, you should be able to click on any Add To Cart butt on and see the change
reflected in your cart count.
Submit the URL to Canvas and the war file to the server.
Enter Web URL
htt ps://
Submit Assignment ?
Project 6 - State Management
8/8
联系我们
QQ:99515681
邮箱:99515681@qq.com
工作时间:8:00-21:00
微信:codinghelp
热点文章
更多
辅导 ecos3010、讲解 java/pyt...
2024-09-07
辅导 data编程、讲解 python设...
2024-09-07
辅导 nur5000 theoretical bas...
2024-09-07
辅导 the impact of minimum w...
2024-09-07
讲解 marketing 301 fall 2024...
2024-09-07
讲解 marketing 301 fall 2024...
2024-09-07
辅导 environmental and natur...
2024-09-07
讲解 tcse1icb individual ass...
2024-09-07
讲解 principles of journalis...
2024-09-07
讲解 lngs1002 2024 assignmen...
2024-09-07
讲解 ece 498 ma: cmos ic des...
2024-09-07
讲解 opre 6369/mis 6369.0w1 ...
2024-09-07
辅导 cmn 4148a – communicat...
2024-09-07
讲解 22748 financial reporti...
2024-09-07
辅导 inft6201 – big data as...
2024-09-07
辅导 cse3smt software measur...
2024-09-07
辅导 corporate and internati...
2024-09-07
辅导 assessment 2 – group a...
2024-09-07
讲解 college writing extende...
2024-09-07
辅导 lin328 basic acoustics ...
2024-09-07
热点标签
mktg2509
csci 2600
38170
lng302
csse3010
phas3226
77938
arch1162
engn4536/engn6536
acx5903
comp151101
phl245
cse12
comp9312
stat3016/6016
phas0038
comp2140
6qqmb312
xjco3011
rest0005
ematm0051
5qqmn219
lubs5062m
eee8155
cege0100
eap033
artd1109
mat246
etc3430
ecmm462
mis102
inft6800
ddes9903
comp6521
comp9517
comp3331/9331
comp4337
comp6008
comp9414
bu.231.790.81
man00150m
csb352h
math1041
eengm4100
isys1002
08
6057cem
mktg3504
mthm036
mtrx1701
mth3241
eeee3086
cmp-7038b
cmp-7000a
ints4010
econ2151
infs5710
fins5516
fin3309
fins5510
gsoe9340
math2007
math2036
soee5010
mark3088
infs3605
elec9714
comp2271
ma214
comp2211
infs3604
600426
sit254
acct3091
bbt405
msin0116
com107/com113
mark5826
sit120
comp9021
eco2101
eeen40700
cs253
ece3114
ecmm447
chns3000
math377
itd102
comp9444
comp(2041|9044)
econ0060
econ7230
mgt001371
ecs-323
cs6250
mgdi60012
mdia2012
comm221001
comm5000
ma1008
engl642
econ241
com333
math367
mis201
nbs-7041x
meek16104
econ2003
comm1190
mbas902
comp-1027
dpst1091
comp7315
eppd1033
m06
ee3025
msci231
bb113/bbs1063
fc709
comp3425
comp9417
econ42915
cb9101
math1102e
chme0017
fc307
mkt60104
5522usst
litr1-uc6201.200
ee1102
cosc2803
math39512
omp9727
int2067/int5051
bsb151
mgt253
fc021
babs2202
mis2002s
phya21
18-213
cege0012
mdia1002
math38032
mech5125
07
cisc102
mgx3110
cs240
11175
fin3020s
eco3420
ictten622
comp9727
cpt111
de114102d
mgm320h5s
bafi1019
math21112
efim20036
mn-3503
fins5568
110.807
bcpm000028
info6030
bma0092
bcpm0054
math20212
ce335
cs365
cenv6141
ftec5580
math2010
ec3450
comm1170
ecmt1010
csci-ua.0480-003
econ12-200
ib3960
ectb60h3f
cs247—assignment
tk3163
ics3u
ib3j80
comp20008
comp9334
eppd1063
acct2343
cct109
isys1055/3412
math350-real
math2014
eec180
stat141b
econ2101
msinm014/msing014/msing014b
fit2004
comp643
bu1002
cm2030
联系我们
- QQ: 99515681 微信:codinghelp
© 2024
www.7daixie.com
站长地图
程序辅导网!