添加搜索框
This commit is contained in:
parent
7ad342217e
commit
e8317fd749
|
@ -23,5 +23,10 @@ module.exports = {
|
||||||
camelcase: 'off',
|
camelcase: 'off',
|
||||||
'no-unused-vars': 'warn',
|
'no-unused-vars': 'warn',
|
||||||
'no-use-before-define': 'off'
|
'no-use-before-define': 'off'
|
||||||
|
},
|
||||||
|
settings: {
|
||||||
|
react: {
|
||||||
|
version: '17.0.0'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,15 @@
|
||||||
{
|
{
|
||||||
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
|
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
|
||||||
"editor.formatOnSave": true
|
"editor.formatOnSave": true,
|
||||||
|
"editor.tabSize": 2,
|
||||||
|
"eslint.trace.server": "verbose",
|
||||||
|
"eslint.validate": [
|
||||||
|
"javascript",
|
||||||
|
"javascriptreact",
|
||||||
|
"typescript",
|
||||||
|
"typescriptreact",
|
||||||
|
"html",
|
||||||
|
"vue",
|
||||||
|
],
|
||||||
|
"eslint.format.enable": true
|
||||||
}
|
}
|
|
@ -1,9 +1,11 @@
|
||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState, useContext } from 'react'
|
||||||
import { search as SearchRepository } from '../api/repository'
|
import { search as SearchRepository } from '../api/repository'
|
||||||
import RepopositoryItem from './RepositoryItem'
|
import RepopositoryItem from './RepositoryItem'
|
||||||
import { RepositorySearchResultItem } from '../api/api'
|
import { RepositorySearchResultItem } from '../api/api'
|
||||||
import classes from './style/RepositoryList.module.css'
|
import classes from './style/RepositoryList.module.css'
|
||||||
import { RepositorySearchCache } from '../utils/cache/RepositorySearch'
|
import { RepositorySearchCache } from '../utils/cache/RepositorySearch'
|
||||||
|
import RepositorySearchInput from './RepositorySearchInput'
|
||||||
|
import { RepositorySearchContext } from '../context/RepositorySearchContext'
|
||||||
|
|
||||||
interface RepositoryListProps {
|
interface RepositoryListProps {
|
||||||
|
|
||||||
|
@ -21,7 +23,12 @@ interface RepositoryListProps {
|
||||||
const DEFAULT_PER_PAGE = 30
|
const DEFAULT_PER_PAGE = 30
|
||||||
|
|
||||||
export default function RepositoryList (props:RepositoryListProps) {
|
export default function RepositoryList (props:RepositoryListProps) {
|
||||||
const cache = RepositorySearchCache(props.keyword, props.max_cache_page)
|
useContext(RepositorySearchContext)
|
||||||
|
|
||||||
|
/** 搜索关键词 */
|
||||||
|
const [keyword, setKeyword] = useState(props.keyword)
|
||||||
|
|
||||||
|
const cache = RepositorySearchCache(keyword, props.max_cache_page)
|
||||||
|
|
||||||
/** 当前页 */
|
/** 当前页 */
|
||||||
const [current_page, setCurrentPage] = useState(1)
|
const [current_page, setCurrentPage] = useState(1)
|
||||||
|
@ -36,10 +43,11 @@ export default function RepositoryList (props:RepositoryListProps) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 调用搜索接口
|
* 调用搜索接口
|
||||||
|
* @param {string} keyword 搜索关键词
|
||||||
* @param {number} page 页码
|
* @param {number} page 页码
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
async function search (page:number):Promise<void> {
|
async function search (keyword:string, page:number):Promise<void> {
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
|
|
||||||
const cache_list = cache.read(page)
|
const cache_list = cache.read(page)
|
||||||
|
@ -54,7 +62,7 @@ export default function RepositoryList (props:RepositoryListProps) {
|
||||||
// 没有缓存,调用接口
|
// 没有缓存,调用接口
|
||||||
try {
|
try {
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
var result = await SearchRepository(props.keyword, page)
|
var result = await SearchRepository(keyword, page)
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log('fetch',err);
|
console.log('fetch',err);
|
||||||
|
@ -80,20 +88,23 @@ export default function RepositoryList (props:RepositoryListProps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
search(1)
|
search(keyword,1)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
function onClickPrev(){
|
function onClickPrev(){
|
||||||
search(current_page-1)
|
search(keyword,current_page-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
function onClickNext(){
|
function onClickNext(){
|
||||||
search(current_page+1)
|
search(keyword,current_page+1)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<RepositorySearchContext.Provider value={{search,setKeyword,keyword,loading}}>
|
||||||
<div className={classes.wrapper}>
|
<div className={classes.wrapper}>
|
||||||
|
<RepositorySearchInput />
|
||||||
<div className={classes['list-wrapper']}>
|
<div className={classes['list-wrapper']}>
|
||||||
|
|
||||||
<ul className={classes.list}>
|
<ul className={classes.list}>
|
||||||
{
|
{
|
||||||
list.map(item => <RepopositoryItem key={item.id} name={item.name} star_count={item.stargazers_count} fork_count={item.forks_count} />)
|
list.map(item => <RepopositoryItem key={item.id} name={item.name} star_count={item.stargazers_count} fork_count={item.forks_count} />)
|
||||||
|
@ -114,5 +125,6 @@ export default function RepositoryList (props:RepositoryListProps) {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
</RepositorySearchContext.Provider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
import React, { useContext } from 'react'
|
||||||
|
import { RepositorySearchContext } from '../context/RepositorySearchContext'
|
||||||
|
|
||||||
|
export default function RepositorySearchInput () {
|
||||||
|
const context = useContext(RepositorySearchContext)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<label htmlFor="keyword-input">
|
||||||
|
搜索关键词:
|
||||||
|
<input type="text" id="keyword-input"
|
||||||
|
value={context.keyword}
|
||||||
|
onChange={({ target }) => {
|
||||||
|
context.setKeyword(target.value)
|
||||||
|
}}
|
||||||
|
onKeyDown={evt => {
|
||||||
|
const value = (evt.target as HTMLInputElement).value
|
||||||
|
if (evt.key.toLocaleLowerCase() === 'enter') {
|
||||||
|
context.setKeyword(value)
|
||||||
|
context.search(value, 1)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<button onClick={() => {
|
||||||
|
context.search(context.keyword, 1)
|
||||||
|
}} disabled={context.loading}>搜索</button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
export const RepositorySearchContext = React.createContext({
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 调用搜索接口
|
||||||
|
* @param {string} keyword 搜索关键词
|
||||||
|
* @param {number} page 页码
|
||||||
|
*/
|
||||||
|
search (keyword:string, page:number) {},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新搜索关键词
|
||||||
|
* @param {string} keyword 搜索关键词
|
||||||
|
*/
|
||||||
|
setKeyword (keyword:string) {},
|
||||||
|
|
||||||
|
/** 搜索关键词 */
|
||||||
|
keyword: '',
|
||||||
|
|
||||||
|
/** 接口调用中 */
|
||||||
|
loading: false
|
||||||
|
})
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
Loading…
Reference in New Issue