more practice for interview
This commit is contained in:
parent
12e5665a1c
commit
743de131d8
27
package-lock.json
generated
27
package-lock.json
generated
@ -8,6 +8,7 @@
|
|||||||
"name": "reac-moment",
|
"name": "reac-moment",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@tanstack/react-query": "^5.85.0",
|
||||||
"axios": "^1.10.0",
|
"axios": "^1.10.0",
|
||||||
"react": "^19.1.0",
|
"react": "^19.1.0",
|
||||||
"react-dom": "^19.1.0"
|
"react-dom": "^19.1.0"
|
||||||
@ -1348,6 +1349,32 @@
|
|||||||
"win32"
|
"win32"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"node_modules/@tanstack/query-core": {
|
||||||
|
"version": "5.83.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.83.1.tgz",
|
||||||
|
"integrity": "sha512-OG69LQgT7jSp+5pPuCfzltq/+7l2xoweggjme9vlbCPa/d7D7zaqv5vN/S82SzSYZ4EDLTxNO1PWrv49RAS64Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/tannerlinsley"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@tanstack/react-query": {
|
||||||
|
"version": "5.85.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.85.0.tgz",
|
||||||
|
"integrity": "sha512-t1HMfToVMGfwEJRya6GG7gbK0luZJd+9IySFNePL1BforU1F3LqQ3tBC2Rpvr88bOrlU6PXyMLgJD0Yzn4ztUw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@tanstack/query-core": "5.83.1"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/tannerlinsley"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^18 || ^19"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/babel__core": {
|
"node_modules/@types/babel__core": {
|
||||||
"version": "7.20.5",
|
"version": "7.20.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@tanstack/react-query": "^5.85.0",
|
||||||
"axios": "^1.10.0",
|
"axios": "^1.10.0",
|
||||||
"react": "^19.1.0",
|
"react": "^19.1.0",
|
||||||
"react-dom": "^19.1.0"
|
"react-dom": "^19.1.0"
|
||||||
|
|||||||
15
src/App.tsx
15
src/App.tsx
@ -4,13 +4,17 @@ import Header from './components/Header'
|
|||||||
import PostList from './components/PostList'
|
import PostList from './components/PostList'
|
||||||
import type { Post } from './components/types'
|
import type { Post } from './components/types'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
import UserContext from './context/UserContext'
|
||||||
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||||
|
import UserList from './components/UserList'
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
|
|
||||||
|
const [username, setUsername] = useState('david');
|
||||||
const [posts, setPosts] = useState<Post[]>([]);
|
const [posts, setPosts] = useState<Post[]>([]);
|
||||||
|
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
|
const queryClient = new QueryClient;
|
||||||
|
|
||||||
|
|
||||||
const fetchPosts = async () => {
|
const fetchPosts = async () => {
|
||||||
@ -61,13 +65,16 @@ function App() {
|
|||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<QueryClientProvider client={queryClient}>
|
||||||
|
<UserContext.Provider value={{ username }}>
|
||||||
|
|
||||||
<Header setRefresh={fetchPosts} searchTerm={searchTerm} setSearchTerm={setSearchTerm} />
|
<Header setRefresh={fetchPosts} searchTerm={searchTerm} setSearchTerm={setSearchTerm} />
|
||||||
|
<UserList/>
|
||||||
<PostList posts={filteredPosts} />
|
<PostList posts={filteredPosts} />
|
||||||
|
|
||||||
</>
|
</UserContext.Provider>
|
||||||
|
</QueryClientProvider>
|
||||||
|
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
6
src/api/types.ts
Normal file
6
src/api/types.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export interface User {
|
||||||
|
id: number,
|
||||||
|
name: string,
|
||||||
|
username: string,
|
||||||
|
email: string
|
||||||
|
}
|
||||||
14
src/api/users.ts
Normal file
14
src/api/users.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import axios from "axios";
|
||||||
|
import type { User } from "./types";
|
||||||
|
|
||||||
|
export const getUsersAPI = async () => {
|
||||||
|
const response = await axios.get<User[]>('https://jsonplaceholder.typicode.com/users');
|
||||||
|
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getUser = async (id: number) => {
|
||||||
|
const response = await axios.get<User>('https://jsonplaceholder.typicode.com/users/' + id);
|
||||||
|
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
@ -1,12 +1,15 @@
|
|||||||
import Block from "./Block";
|
import Block from "./Block";
|
||||||
import type { HeaderProps } from "./types";
|
import type { HeaderProps } from "./types";
|
||||||
import styles from "./Header.module.css";
|
import styles from "./Header.module.css";
|
||||||
|
import { useContext } from "react";
|
||||||
|
import UserContext from "../context/UserContext";
|
||||||
|
|
||||||
function Header({setRefresh, searchTerm, setSearchTerm}:HeaderProps) {
|
function Header({setRefresh, searchTerm, setSearchTerm}:HeaderProps) {
|
||||||
|
const user = useContext(UserContext);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Block title="Header">
|
<Block title="Header">
|
||||||
|
<span>{user.username}</span>
|
||||||
<hr></hr>
|
<hr></hr>
|
||||||
<div className={styles.refreshAndSearch}>
|
<div className={styles.refreshAndSearch}>
|
||||||
<button className={styles.refreshBtn} onClick={() => setRefresh()}>Refresh</button>
|
<button className={styles.refreshBtn} onClick={() => setRefresh()}>Refresh</button>
|
||||||
|
|||||||
23
src/components/UserList.tsx
Normal file
23
src/components/UserList.tsx
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { useUsers, useUser } from "../query/users";
|
||||||
|
import Block from "./Block";
|
||||||
|
|
||||||
|
function UserList(){
|
||||||
|
const {data, isLoading, isFetching} = useUsers();
|
||||||
|
const {data: user1data, isLoading: user1Loading} = useUser(1);
|
||||||
|
|
||||||
|
if(isLoading || user1Loading)
|
||||||
|
return <div>Loading...</div>
|
||||||
|
|
||||||
|
return(
|
||||||
|
<Block title="users">
|
||||||
|
<h2>User List</h2>
|
||||||
|
{data?.map(user => <p>{user.username}</p>)}
|
||||||
|
|
||||||
|
<h2>USer info</h2>
|
||||||
|
<p>{user1data?.email}</p>
|
||||||
|
</Block>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default UserList;
|
||||||
7
src/context/UserContext.ts
Normal file
7
src/context/UserContext.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import { createContext } from "react";
|
||||||
|
|
||||||
|
const UserContext = createContext({
|
||||||
|
username: "david"
|
||||||
|
})
|
||||||
|
|
||||||
|
export default UserContext;
|
||||||
21
src/query/users.ts
Normal file
21
src/query/users.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
import { getUser, getUsersAPI } from "../api/users";
|
||||||
|
|
||||||
|
export const useUsers = () => {
|
||||||
|
const { data, isFetching, isLoading } = useQuery({
|
||||||
|
queryKey: ['users'],
|
||||||
|
queryFn: getUsersAPI
|
||||||
|
});
|
||||||
|
|
||||||
|
return {data, isFetching, isLoading};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useUser = (id: number) => {
|
||||||
|
const{data, isFetching, isLoading} = useQuery({
|
||||||
|
queryKey: ['user', id],
|
||||||
|
queryFn: () => getUser(id)
|
||||||
|
})
|
||||||
|
|
||||||
|
return {data, isLoading, isFetching};
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user