Skip to content

Commit

Permalink
将图片数据和搜索功能移到context中
Browse files Browse the repository at this point in the history
  • Loading branch information
slince-zero committed Apr 23, 2024
1 parent 9301f0b commit c099444
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 59 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,9 @@ export default {
- Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked`
- Optionally add `plugin:@typescript-eslint/stylistic-type-checked`
- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list


## useContext 很灵活

通过 createContext 创建一个 contextProvider 就可以在任意组件里面传递数据,而且很灵活,可以直接在跟组件里面用 contextProvider 来包裹根组件。
也可以用它包裹任意你想传递数据的组件当中。
81 changes: 81 additions & 0 deletions src/context/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import {
createContext,
useEffect,
useState,
KeyboardEvent,
ReactNode,
} from 'react'
import ImageItem from '@/page/left/ImageItem'

export const ImgContext = createContext({
imgList: [],
setImgList: () => {},
} as any)

export default function ImgContextProvider({
children,
}: {
children: ReactNode
}) {
const [imageList, setImageList] = useState<ImageItem[]>([])
const [searchValue, setSearchValue] = useState('')
const [isLoading, setIsLoading] = useState(false)
// 获取图片
async function getImage(searchText: string = '') {
try {
setIsLoading(true)
const accessKey = 'cPSLU8ro2LKkaLQ71-RKKFFwb2g-_DIx9NCf27YnCHs'
const endpoint =
searchText.length > 0
? `https://api.unsplash.com/search/photos`
: `https://api.unsplash.com/photos`
const queryParam = searchText
? `&query=${encodeURIComponent(searchText)}`
: ''
const res = await fetch(
`${endpoint}?per_page=30${queryParam}&client_id=${accessKey}`
)
const data = await res.json()

if (data && data.results) {
// 如果是使用搜索API,结果会在data.results中
setImageList(data.results)
} else {
setImageList(data) // 直接访问 Unsplash collections/photos 数据在顶层
}
// console.log(imageList,'33')
} catch (e) {
console.error(e)
} finally {
setIsLoading(false)
setSearchValue('')
}
}

useEffect(() => {
getImage()
}, [])

// 按下回车事件
function onSearchKeyDown(e: KeyboardEvent<HTMLInputElement> | KeyboardEvent) {
if (e.key === 'Enter') {
getImage(searchValue)
}
}

return (
<ImgContext.Provider
value={{
imageList,
setImageList,
searchValue,
setSearchValue,
isLoading,
setIsLoading,
getImage,
onSearchKeyDown,
}}>
{children}
</ImgContext.Provider>
)
}
5 changes: 4 additions & 1 deletion src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './index.css'
import { NextUIProvider } from '@nextui-org/react'
import ImgContextProvider from '@/context'

ReactDOM.createRoot(document.getElementById('root')!).render(
<NextUIProvider>
<main className='dark text-foreground bg-background'>
<App />
<ImgContextProvider>
<App />
</ImgContextProvider>
</main>
</NextUIProvider>
)
1 change: 1 addition & 0 deletions src/page/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import LeftBoard from '@/page/left'
import CenterBoard from '@/page/center'
import RightBoard from '@/page/right'

export default function Main() {
return (
<div className='conatainer flex h-screen overflow-x-hidden'>
Expand Down
86 changes: 28 additions & 58 deletions src/page/left/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,55 +9,18 @@ import {
ScrollShadow,
} from '@nextui-org/react'
import { ImgLogo, UploadLogo } from './logo'
import { ImgContext } from '@/context'
import { Key, useContext } from 'react'

import { useState, useEffect, KeyboardEvent } from 'react'
import ImageItem from './ImageItem'
export default function LeftBoard() {
const [imageList, setImageList] = useState<ImageItem[]>([])
const [searchValue, setSearchValue] = useState('')
const [isLoading, setIsLoading] = useState(false)

// 获取图片
async function getImage(searchText: string = '') {
try {
setIsLoading(true)
const accessKey = 'cPSLU8ro2LKkaLQ71-RKKFFwb2g-_DIx9NCf27YnCHs'
const endpoint =
searchText.length > 0
? `https://api.unsplash.com/search/photos`
: `https://api.unsplash.com/photos`
const queryParam = searchText
? `&query=${encodeURIComponent(searchText)}`
: ''
const res = await fetch(
`${endpoint}?per_page=30${queryParam}&client_id=${accessKey}`
)
const data = await res.json()
if (data && data.results) {
// 如果是使用搜索API,结果会在data.results中
setImageList(data.results)
} else {
setImageList(data) // 直接访问 Unsplash collections/photos 数据在顶层
}
console.log(data);

} catch (e) {
console.error(e)
} finally {
setIsLoading(false)
}
}

useEffect(() => {
getImage()
}, [])

// 按下回车事件
function onSearchKeyDown(e: KeyboardEvent<HTMLInputElement> | KeyboardEvent) {
if (e.key === 'Enter') {
getImage(searchValue)
}
}
const {
imageList,
searchValue,
setSearchValue,
isLoading,
getImage,
onSearchKeyDown,
} = useContext(ImgContext)

return (
<div className='flex flex-col bg-slate-500 h-screen'>
Expand All @@ -81,21 +44,28 @@ export default function LeftBoard() {

<ScrollShadow>
<div className='flex-grow overflow-y-scroll overflow-x-hidden justify-center flex flex-wrap scrollbar-thin scrollbar-color-auto '>
{imageList.length == 0 ? (
{imageList && imageList?.length == 0 ? (
<div className='flex items-center justify-center transition-transform duration-200 transform hover:scale-105 rounded m-2 cursor-pointer w-5/12 object-cover h-screen'>
没有找到图片
</div>
) : (
imageList.map((item) => {
return (
<img
key={item?.id}
src={item?.urls.small}
alt={item?.alt_description}
className='transition-transform duration-200 transform hover:scale-105 rounded m-2 cursor-pointer w-5/12 object-cover h-24'
/>
)
})
imageList &&
imageList.map(
(item: {
id: Key | null | undefined
urls: { small: string | undefined }
alt_description: string | undefined
}) => {
return (
<img
key={item?.id}
src={item?.urls.small}
alt={item?.alt_description}
className='transition-transform duration-200 transform hover:scale-105 rounded m-2 cursor-pointer w-5/12 object-cover h-24'
/>
)
}
)
)}
</div>
</ScrollShadow>
Expand Down

0 comments on commit c099444

Please sign in to comment.