item.login.uuid}
52 | />
53 | );
54 | };
55 |
56 | const styles = StyleSheet.create({
57 | itemContainer: {
58 | flexDirection: "row",
59 | padding: 10,
60 | borderBottomWidth: 1,
61 | borderBottomColor: "#ddd",
62 | alignItems: "center",
63 | },
64 | avatar: {
65 | width: 50,
66 | height: 50,
67 | borderRadius: 25,
68 | marginRight: 10,
69 | },
70 | infoContainer: {
71 | flex: 1,
72 | },
73 | name: {
74 | fontSize: 16,
75 | fontWeight: "bold",
76 | },
77 | email: {
78 | fontSize: 14,
79 | color: "#666",
80 | },
81 | loadingText: {
82 | textAlign: "center",
83 | marginTop: 20,
84 | },
85 | errorText: {
86 | textAlign: "center",
87 | marginTop: 20,
88 | color: "red",
89 | },
90 | });
91 |
92 | export default RandomUserComponent;
93 |
--------------------------------------------------------------------------------
/11. useReducer/app/components/Counter.tsx:
--------------------------------------------------------------------------------
1 | // // The useReducer Hook is the alternative to useState Hook.
2 | // If you find yourself keeping track of multiple pieces of state that rely on complex logic, useReducer may be useful.
3 |
4 | // The useReducer Hook returns the current (state) and a (dispatch) method.
5 |
6 | // State as the name suggest will be the "state" of your component.
7 | // dispatch will allow you to change that state, Think of it is like [val, setVal]
8 |
9 | // useReducer accepts two parameters (reducer, initialState)
10 |
11 | // The reducer function contains your custom state logic
12 | // The initialState can be a simple value but generally will contain an object.
13 |
14 | // 1 👇
15 | // import { useReducer } from "react";
16 |
17 | // const Counter = () => {
18 | // // 2 👇
19 | // const [state, dispatch] = useReducer(reducer, initialState);
20 |
21 | // return (
22 | //
23 | // {/* 6 👇 */}
24 | //
25 | //
26 | //
27 | //
{state.count}
28 | //
29 | // );
30 | // };
31 |
32 | // // 3 👇
33 | // const initialState = { count: 0 };
34 |
35 | // // 4 👇
36 | // const reducer = (state, action) => {
37 | // // 5 👇
38 | // switch (action.type) {
39 | // case "increment":
40 | // return {
41 | // ...state,
42 | // count: state.count + 1,
43 | // };
44 | // case "decrement":
45 | // return {
46 | // ...state,
47 | // count: state.count - 1,
48 | // };
49 | // case "reset":
50 | // return {
51 | // ...state,
52 | // count: 0,
53 | // };
54 | // default:
55 | // return state;
56 | // }
57 | // };
58 | // ----------------------------------
59 |
60 | import React, { useReducer } from "react";
61 | import { View, Text, Button, StyleSheet } from "react-native";
62 |
63 | interface State {
64 | count: number;
65 | }
66 |
67 | type Action = { type: "increment" } | { type: "decrement" };
68 |
69 | const initialState: State = { count: 0 };
70 |
71 | function reducer(state: State, action: Action): State {
72 | switch (action.type) {
73 | case "increment":
74 | return { count: state.count + 1 };
75 | case "decrement":
76 | return { count: state.count - 1 };
77 | default:
78 | throw new Error("Unhandled action type");
79 | }
80 | }
81 |
82 | const Counter: React.FC = () => {
83 | const [state, dispatch] = useReducer(reducer, initialState);
84 |
85 | return (
86 |
87 | Count: {state.count}
88 |
97 | );
98 | };
99 |
100 | export default Counter;
101 |
--------------------------------------------------------------------------------
/11. useReducer/Challenges/src/components/1. Todo.tsx:
--------------------------------------------------------------------------------
1 | import React, { useReducer, useState } from "react";
2 | import {
3 | View,
4 | Text,
5 | TextInput,
6 | Button,
7 | FlatList,
8 | StyleSheet,
9 | TouchableOpacity,
10 | } from "react-native";
11 |
12 | // Define the types for the state and actions
13 | interface Todo {
14 | id: string;
15 | text: string;
16 | }
17 |
18 | interface State {
19 | todos: Todo[];
20 | }
21 |
22 | interface AddTodoAction {
23 | type: "ADD_TODO";
24 | payload: string;
25 | }
26 |
27 | interface RemoveTodoAction {
28 | type: "REMOVE_TODO";
29 | payload: string;
30 | }
31 |
32 | type Action = AddTodoAction | RemoveTodoAction;
33 |
34 | // Define initial state
35 | const initialState: State = { todos: [] };
36 |
37 | // Define reducer function
38 | const reducer = (state: State, action: Action): State => {
39 | switch (action.type) {
40 | case "ADD_TODO":
41 | return {
42 | todos: [
43 | ...state.todos,
44 | { id: Date.now().toString(), text: action.payload },
45 | ],
46 | };
47 | case "REMOVE_TODO":
48 | return {
49 | todos: state.todos.filter((todo) => todo.id !== action.payload),
50 | };
51 | default:
52 | return state;
53 | }
54 | };
55 |
56 | const ToDoApp: React.FC = () => {
57 | const [state, dispatch] = useReducer(reducer, initialState);
58 | const [inputValue, setInputValue] = useState("");
59 |
60 | const handleAddTodo = () => {
61 | if (inputValue.trim()) {
62 | dispatch({ type: "ADD_TODO", payload: inputValue });
63 | setInputValue("");
64 | }
65 | };
66 |
67 | const handleRemoveTodo = (id: string) => {
68 | dispatch({ type: "REMOVE_TODO", payload: id });
69 | };
70 |
71 | return (
72 |
73 |
79 |
80 |
81 |
82 | item.id}
85 | renderItem={({ item }) => (
86 |
87 | {item.text}
88 | handleRemoveTodo(item.id)}>
89 | Remove
90 |
91 |
92 | )}
93 | />
94 |
95 | );
96 | };
97 |
98 | const styles = StyleSheet.create({
99 | input: {
100 | height: 40,
101 | borderColor: "gray",
102 | borderWidth: 1,
103 | marginBottom: 10,
104 | paddingHorizontal: 10,
105 | },
106 | todoItem: {
107 | flexDirection: "row",
108 | justifyContent: "space-between",
109 | alignItems: "center",
110 | paddingVertical: 10,
111 | borderBottomWidth: 1,
112 | borderBottomColor: "#ccc",
113 | },
114 | todoText: {
115 | fontSize: 16,
116 | },
117 | removeButton: {
118 | color: "red",
119 | },
120 | });
121 |
122 | export default ToDoApp;
123 |
--------------------------------------------------------------------------------
/11. useReducer/Challenges/src/components/2. UserProfile.tsx:
--------------------------------------------------------------------------------
1 | import { useReducer, useState } from "react";
2 | import {
3 | View,
4 | Text,
5 | TextInput,
6 | Button,
7 | FlatList,
8 | StyleSheet,
9 | TouchableOpacity,
10 | } from "react-native";
11 |
12 | // Define the types for the state and actions
13 | interface Profile {
14 | id: string;
15 | name: string;
16 | age: number;
17 | }
18 |
19 | interface State {
20 | profiles: Profile[];
21 | }
22 |
23 | interface AddProfileAction {
24 | type: "ADD_PROFILE";
25 | payload: { name: string; age: number };
26 | }
27 |
28 | interface RemoveProfileAction {
29 | type: "REMOVE_PROFILE";
30 | payload: string;
31 | }
32 |
33 | interface UpdateProfileAction {
34 | type: "UPDATE_PROFILE";
35 | payload: { id: string; name: string; age: number };
36 | }
37 |
38 | type Action = AddProfileAction | RemoveProfileAction | UpdateProfileAction;
39 |
40 | // Define initial state
41 | const initialState: State = { profiles: [] };
42 |
43 | // Define reducer function
44 | const reducer = (state: State, action: Action): State => {
45 | switch (action.type) {
46 | case "ADD_PROFILE":
47 | return {
48 | profiles: [
49 | ...state.profiles,
50 | {
51 | id: Date.now().toString(),
52 | name: action.payload.name,
53 | age: action.payload.age,
54 | },
55 | ],
56 | };
57 | case "REMOVE_PROFILE":
58 | return {
59 | profiles: state.profiles.filter(
60 | (profile) => profile.id !== action.payload
61 | ),
62 | };
63 | case "UPDATE_PROFILE":
64 | return {
65 | profiles: state.profiles.map((profile) =>
66 | profile.id === action.payload.id
67 | ? { ...profile, name: action.payload.name, age: action.payload.age }
68 | : profile
69 | ),
70 | };
71 | default:
72 | return state;
73 | }
74 | };
75 |
76 | const UserProfileApp: React.FC = () => {
77 | const [state, dispatch] = useReducer(reducer, initialState);
78 | const [name, setName] = useState("");
79 | const [age, setAge] = useState("");
80 | const [editingId, setEditingId] = useState(null);
81 |
82 | const handleAddProfile = () => {
83 | if (name.trim() && age.trim()) {
84 | dispatch({
85 | type: "ADD_PROFILE",
86 | payload: { name, age: parseInt(age, 10) },
87 | });
88 | setName("");
89 | setAge("");
90 | }
91 | };
92 |
93 | const handleUpdateProfile = (id: string) => {
94 | if (name.trim() && age.trim()) {
95 | dispatch({
96 | type: "UPDATE_PROFILE",
97 | payload: { id, name, age: parseInt(age, 10) },
98 | });
99 | setName("");
100 | setAge("");
101 | setEditingId(null);
102 | }
103 | };
104 |
105 | const handleRemoveProfile = (id: string) => {
106 | dispatch({ type: "REMOVE_PROFILE", payload: id });
107 | };
108 |
109 | return (
110 |
111 |
117 |
124 | {editingId ? (
125 | handleUpdateProfile(editingId)}
128 | />
129 | ) : (
130 |
131 | )}
132 | item.id}
135 | renderItem={({ item }) => (
136 |
137 |
138 | {item.name}, {item.age} years old
139 |
140 | {
142 | setName(item.name);
143 | setAge(item.age.toString());
144 | setEditingId(item.id);
145 | }}
146 | >
147 | Edit
148 |
149 | handleRemoveProfile(item.id)}>
150 | Remove
151 |
152 |
153 | )}
154 | />
155 |
156 | );
157 | };
158 |
159 | const styles = StyleSheet.create({
160 | input: {
161 | height: 40,
162 | borderColor: "gray",
163 | borderWidth: 1,
164 | marginBottom: 10,
165 | paddingHorizontal: 10,
166 | },
167 | profileItem: {
168 | flexDirection: "row",
169 | justifyContent: "space-between",
170 | alignItems: "center",
171 | paddingVertical: 10,
172 | borderBottomWidth: 1,
173 | borderBottomColor: "#ccc",
174 | },
175 | profileText: {
176 | fontSize: 16,
177 | flex: 1,
178 | },
179 | editButton: {
180 | color: "blue",
181 | marginRight: 10,
182 | },
183 | removeButton: {
184 | color: "red",
185 | },
186 | });
187 |
188 | export default UserProfileApp;
189 |
--------------------------------------------------------------------------------
/11. useReducer/Challenges/src/components/3. ShoppingCart.tsx:
--------------------------------------------------------------------------------
1 | import React, { useReducer, useState } from "react";
2 | import {
3 | View,
4 | Text,
5 | TextInput,
6 | Button,
7 | FlatList,
8 | StyleSheet,
9 | TouchableOpacity,
10 | } from "react-native";
11 |
12 | // Define the types for the state and actions
13 | interface Profile {
14 | id: string;
15 | name: string;
16 | age: number;
17 | }
18 |
19 | interface State {
20 | profiles: Profile[];
21 | }
22 |
23 | interface AddProfileAction {
24 | type: "ADD_PROFILE";
25 | payload: { name: string; age: number };
26 | }
27 |
28 | interface RemoveProfileAction {
29 | type: "REMOVE_PROFILE";
30 | payload: string;
31 | }
32 |
33 | interface UpdateProfileAction {
34 | type: "UPDATE_PROFILE";
35 | payload: { id: string; name: string; age: number };
36 | }
37 |
38 | type Action = AddProfileAction | RemoveProfileAction | UpdateProfileAction;
39 |
40 | // Define initial state
41 | const initialState: State = { profiles: [] };
42 |
43 | // Define reducer function
44 | const reducer = (state: State, action: Action): State => {
45 | switch (action.type) {
46 | case "ADD_PROFILE":
47 | return {
48 | profiles: [
49 | ...state.profiles,
50 | {
51 | id: Date.now().toString(),
52 | name: action.payload.name,
53 | age: action.payload.age,
54 | },
55 | ],
56 | };
57 | case "REMOVE_PROFILE":
58 | return {
59 | profiles: state.profiles.filter(
60 | (profile) => profile.id !== action.payload
61 | ),
62 | };
63 | case "UPDATE_PROFILE":
64 | return {
65 | profiles: state.profiles.map((profile) =>
66 | profile.id === action.payload.id
67 | ? { ...profile, name: action.payload.name, age: action.payload.age }
68 | : profile
69 | ),
70 | };
71 | default:
72 | return state;
73 | }
74 | };
75 |
76 | const UserProfileApp: React.FC = () => {
77 | const [state, dispatch] = useReducer(reducer, initialState);
78 | const [name, setName] = useState("");
79 | const [age, setAge] = useState("");
80 | const [editingId, setEditingId] = useState(null);
81 |
82 | const handleAddProfile = () => {
83 | if (name.trim() && age.trim()) {
84 | dispatch({
85 | type: "ADD_PROFILE",
86 | payload: { name, age: parseInt(age, 10) },
87 | });
88 | setName("");
89 | setAge("");
90 | }
91 | };
92 |
93 | const handleUpdateProfile = (id: string) => {
94 | if (name.trim() && age.trim()) {
95 | dispatch({
96 | type: "UPDATE_PROFILE",
97 | payload: { id, name, age: parseInt(age, 10) },
98 | });
99 | setName("");
100 | setAge("");
101 | setEditingId(null);
102 | }
103 | };
104 |
105 | const handleRemoveProfile = (id: string) => {
106 | dispatch({ type: "REMOVE_PROFILE", payload: id });
107 | };
108 |
109 | return (
110 |
111 |
117 |
124 | {editingId ? (
125 | handleUpdateProfile(editingId)}
128 | />
129 | ) : (
130 |
131 | )}
132 | item.id}
135 | renderItem={({ item }) => (
136 |
137 |
138 | {item.name}, {item.age} years old
139 |
140 | {
142 | setName(item.name);
143 | setAge(item.age.toString());
144 | setEditingId(item.id);
145 | }}
146 | >
147 | Edit
148 |
149 | handleRemoveProfile(item.id)}>
150 | Remove
151 |
152 |
153 | )}
154 | />
155 |
156 | );
157 | };
158 |
159 | const styles = StyleSheet.create({
160 | input: {
161 | height: 40,
162 | borderColor: "gray",
163 | borderWidth: 1,
164 | marginBottom: 10,
165 | paddingHorizontal: 10,
166 | },
167 | profileItem: {
168 | flexDirection: "row",
169 | justifyContent: "space-between",
170 | alignItems: "center",
171 | paddingVertical: 10,
172 | borderBottomWidth: 1,
173 | borderBottomColor: "#ccc",
174 | },
175 | profileText: {
176 | fontSize: 16,
177 | flex: 1,
178 | },
179 | editButton: {
180 | color: "blue",
181 | marginRight: 10,
182 | },
183 | removeButton: {
184 | color: "red",
185 | },
186 | });
187 |
188 | export default UserProfileApp;
189 |
--------------------------------------------------------------------------------
/05. FlatList/Challenges/src/components/HugeList.tsx:
--------------------------------------------------------------------------------
1 | import { FlatList, StyleSheet, View, Text, Image } from "react-native";
2 |
3 | interface Product {
4 | image: string;
5 | name: string;
6 | rating: number;
7 | price: number;
8 | }
9 |
10 | const HugeList = () => {
11 | const products = [
12 | {
13 | image: "https://picsum.photos/200/300?random=1",
14 | name: "Product 1",
15 | rating: 4.5,
16 | price: 29.99,
17 | },
18 | {
19 | image: "https://picsum.photos/200/300?random=2",
20 | name: "Product 2",
21 | rating: 4.0,
22 | price: 19.99,
23 | },
24 | {
25 | image: "https://picsum.photos/200/300?random=3",
26 | name: "Product 3",
27 | rating: 3.5,
28 | price: 24.99,
29 | },
30 | {
31 | image: "https://picsum.photos/200/300?random=4",
32 | name: "Product 4",
33 | rating: 5.0,
34 | price: 39.99,
35 | },
36 | {
37 | image: "https://picsum.photos/200/300?random=5",
38 | name: "Product 5",
39 | rating: 4.2,
40 | price: 34.99,
41 | },
42 | {
43 | image: "https://picsum.photos/200/300?random=6",
44 | name: "Product 6",
45 | rating: 3.9,
46 | price: 21.99,
47 | },
48 | {
49 | image: "https://picsum.photos/200/300?random=7",
50 | name: "Product 7",
51 | rating: 4.3,
52 | price: 28.99,
53 | },
54 | {
55 | image: "https://picsum.photos/200/300?random=8",
56 | name: "Product 8",
57 | rating: 3.7,
58 | price: 23.99,
59 | },
60 | {
61 | image: "https://picsum.photos/200/300?random=9",
62 | name: "Product 9",
63 | rating: 4.6,
64 | price: 32.99,
65 | },
66 | {
67 | image: "https://picsum.photos/200/300?random=10",
68 | name: "Product 10",
69 | rating: 4.1,
70 | price: 27.99,
71 | },
72 | {
73 | image: "https://picsum.photos/200/300?random=11",
74 | name: "Product 11",
75 | rating: 3.8,
76 | price: 22.99,
77 | },
78 | {
79 | image: "https://picsum.photos/200/300?random=12",
80 | name: "Product 12",
81 | rating: 4.4,
82 | price: 30.99,
83 | },
84 | {
85 | image: "https://picsum.photos/200/300?random=13",
86 | name: "Product 13",
87 | rating: 3.6,
88 | price: 26.99,
89 | },
90 | {
91 | image: "https://picsum.photos/200/300?random=14",
92 | name: "Product 14",
93 | rating: 4.7,
94 | price: 35.99,
95 | },
96 | {
97 | image: "https://picsum.photos/200/300?random=15",
98 | name: "Product 15",
99 | rating: 4.2,
100 | price: 31.99,
101 | },
102 | {
103 | image: "https://picsum.photos/200/300?random=16",
104 | name: "Product 16",
105 | rating: 4.0,
106 | price: 25.99,
107 | },
108 | {
109 | image: "https://picsum.photos/200/300?random=17",
110 | name: "Product 17",
111 | rating: 3.9,
112 | price: 20.99,
113 | },
114 | {
115 | image: "https://picsum.photos/200/300?random=18",
116 | name: "Product 18",
117 | rating: 4.3,
118 | price: 29.99,
119 | },
120 | {
121 | image: "https://picsum.photos/200/300?random=19",
122 | name: "Product 19",
123 | rating: 4.5,
124 | price: 33.99,
125 | },
126 | {
127 | image: "https://picsum.photos/200/300?random=20",
128 | name: "Product 20",
129 | rating: 4.1,
130 | price: 28.99,
131 | },
132 | {
133 | image: "https://picsum.photos/200/300?random=21",
134 | name: "Product 21",
135 | rating: 3.7,
136 | price: 24.99,
137 | },
138 | {
139 | image: "https://picsum.photos/200/300?random=22",
140 | name: "Product 22",
141 | rating: 4.4,
142 | price: 32.99,
143 | },
144 | {
145 | image: "https://picsum.photos/200/300?random=23",
146 | name: "Product 23",
147 | rating: 4.0,
148 | price: 27.99,
149 | },
150 | {
151 | image: "https://picsum.photos/200/300?random=24",
152 | name: "Product 24",
153 | rating: 3.6,
154 | price: 21.99,
155 | },
156 | {
157 | image: "https://picsum.photos/200/300?random=25",
158 | name: "Product 25",
159 | rating: 4.6,
160 | price: 36.99,
161 | },
162 | {
163 | image: "https://picsum.photos/200/300?random=26",
164 | name: "Product 26",
165 | rating: 4.1,
166 | price: 30.99,
167 | },
168 | {
169 | image: "https://picsum.photos/200/300?random=27",
170 | name: "Product 27",
171 | rating: 3.8,
172 | price: 25.99,
173 | },
174 | {
175 | image: "https://picsum.photos/200/300?random=28",
176 | name: "Product 28",
177 | rating: 4.3,
178 | price: 31.99,
179 | },
180 | {
181 | image: "https://picsum.photos/200/300?random=29",
182 | name: "Product 29",
183 | rating: 4.2,
184 | price: 29.99,
185 | },
186 | {
187 | image: "https://picsum.photos/200/300?random=30",
188 | name: "Product 30",
189 | rating: 4.0,
190 | price: 26.99,
191 | },
192 | {
193 | image: "https://picsum.photos/200/300?random=31",
194 | name: "Product 31",
195 | rating: 3.9,
196 | price: 23.99,
197 | },
198 | {
199 | image: "https://picsum.photos/200/300?random=32",
200 | name: "Product 32",
201 | rating: 4.4,
202 | price: 34.99,
203 | },
204 | {
205 | image: "https://picsum.photos/200/300?random=33",
206 | name: "Product 33",
207 | rating: 4.1,
208 | price: 28.99,
209 | },
210 | {
211 | image: "https://picsum.photos/200/300?random=34",
212 | name: "Product 34",
213 | rating: 3.7,
214 | price: 22.99,
215 | },
216 | {
217 | image: "https://picsum.photos/200/300?random=35",
218 | name: "Product 35",
219 | rating: 4.5,
220 | price: 33.99,
221 | },
222 | {
223 | image: "https://picsum.photos/200/300?random=36",
224 | name: "Product 36",
225 | rating: 4.0,
226 | price: 27.99,
227 | },
228 | {
229 | image: "https://picsum.photos/200/300?random=37",
230 | name: "Product 37",
231 | rating: 3.6,
232 | price: 21.99,
233 | },
234 | {
235 | image: "https://picsum.photos/200/300?random=38",
236 | name: "Product 38",
237 | rating: 4.6,
238 | price: 35.99,
239 | },
240 | {
241 | image: "https://picsum.photos/200/300?random=39",
242 | name: "Product 39",
243 | rating: 4.2,
244 | price: 31.99,
245 | },
246 | {
247 | image: "https://picsum.photos/200/300?random=40",
248 | name: "Product 40",
249 | rating: 4.3,
250 | price: 30.99,
251 | },
252 | {
253 | image: "https://picsum.photos/200/300?random=41",
254 | name: "Product 41",
255 | rating: 4.1,
256 | price: 26.99,
257 | },
258 | {
259 | image: "https://picsum.photos/200/300?random=42",
260 | name: "Product 42",
261 | rating: 3.8,
262 | price: 24.99,
263 | },
264 | {
265 | image: "https://picsum.photos/200/300?random=43",
266 | name: "Product 43",
267 | rating: 4.4,
268 | price: 33.99,
269 | },
270 | {
271 | image: "https://picsum.photos/200/300?random=44",
272 | name: "Product 44",
273 | rating: 4.2,
274 | price: 29.99,
275 | },
276 | {
277 | image: "https://picsum.photos/200/300?random=45",
278 | name: "Product 45",
279 | rating: 3.7,
280 | price: 22.99,
281 | },
282 | {
283 | image: "https://picsum.photos/200/300?random=46",
284 | name: "Product 46",
285 | rating: 4.5,
286 | price: 34.99,
287 | },
288 | {
289 | image: "https://picsum.photos/200/300?random=47",
290 | name: "Product 47",
291 | rating: 4.1,
292 | price: 30.99,
293 | },
294 | {
295 | image: "https://picsum.photos/200/300?random=48",
296 | name: "Product 48",
297 | rating: 4.0,
298 | price: 25.99,
299 | },
300 | {
301 | image: "https://picsum.photos/200/300?random=49",
302 | name: "Product 49",
303 | rating: 3.9,
304 | price: 21.99,
305 | },
306 | {
307 | image: "https://picsum.photos/200/300?random=50",
308 | name: "Product 50",
309 | rating: 4.3,
310 | price: 32.99,
311 | },
312 | ];
313 |
314 | const renderItem = ({ item }: { item: Product }) => (
315 |
316 |
317 | {item.name}
318 | Rating: {item.rating}
319 | Price: ${item.price}
320 |
321 | );
322 |
323 | return (
324 | index.toString()}
328 | />
329 | );
330 | };
331 |
332 | const styles = StyleSheet.create({
333 | productContainer: {
334 | flex: 1,
335 | alignItems: "center",
336 | padding: 10,
337 | marginBottom: 10,
338 | backgroundColor: "#fff",
339 | borderRadius: 10,
340 | shadowColor: "#000",
341 | shadowOffset: { width: 0, height: 2 },
342 | shadowOpacity: 0.1,
343 | shadowRadius: 5,
344 | elevation: 5,
345 | },
346 | image: {
347 | width: 200,
348 | height: 300,
349 | borderRadius: 10,
350 | },
351 | name: {
352 | fontSize: 18,
353 | fontWeight: "bold",
354 | marginTop: 10,
355 | },
356 | rating: {
357 | fontSize: 16,
358 | color: "#888",
359 | marginTop: 5,
360 | },
361 | price: {
362 | fontSize: 16,
363 | color: "#000",
364 | marginTop: 5,
365 | },
366 | });
367 |
368 | export default HugeList;
369 |
--------------------------------------------------------------------------------