我在实现搜索参数时遇到了react-router@6
问题。
首先,应用可以使用搜索表单进行搜索(例如,如果用户搜索dark
,应用将定向到localhost:3000/search?query=dark
以显示结果),
我也可以使用搜索栏中的URL来定向到正确的页面和结果(比如用户使用的URL是localhost:3000/search?query=dark
,它会直接跳转到页面显示结果),现在的问题是用户在搜索表单中输入时,它会立即添加搜索参数来更改URL,我知道这是由于handleChange
函数中的setSearchParams()
造成的。但是有没有什么方法可以在输入搜索表单时***不***更改URL?
import React from 'react'
import Navbar from './Navbar'
import create from 'zustand'
import { useState, useEffect } from 'react'
import { useLocation, useNavigate, useSearchParams } from 'react-router-dom'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faTriangleExclamation } from '@fortawesome/free-solid-svg-icons'
// Zustand
let store = (set) => ({
// input: '',
// setInput: (value) => set({ input: value }),
allImages: [],
setAllImages: (images) => set({ allImages: images}),
totalResults: null,
setTotalResults: (num) => set({ totalResults: num}),
})
export const useMain = create(store)
function Header() {
const [error, setError] = useState(null)
const [showError, setShowError] = useState(false)
const [fadeOut, setFadeOut] = useState(false)
const [page, setPage] = useState(1)
const [searchParams, setSearchParams] = useSearchParams()
const query = searchParams.get('query') || ''
const allImages = useMain(state => state.allImages)
const setAllImages = useMain(state => state.setAllImages)
// const totalResults = useMain(state => state.totalResults)
const setTotalResults = useMain(state => state.setTotalResults)
function handleChange(event) {
// setInput(event.target.value)
setSearchParams({query: event.target.value})
}
async function fetchImages() {
try {
const res = await fetch(`https://api.unsplash.com/search/photos?&page=${page}&per_page=30&query=${query}&client_id=${process.env.REACT_APP_UNSPLASH_API_KEY}`)
const data = await res.json()
if (data.total !== 0) {
setAllImages(data.results)
setTotalResults(data.total)
}
} catch(error) {
setError(error)
}
}
let navigate = useNavigate()
const handleSubmit = async (event) => {
event.preventDefault()
fetchImages()
navigate(`/search?query=${query}`)
}
const location = useLocation()
useEffect(() => {
if (location.pathname === '/search' && allImages.length === 0) {
fetchImages()
navigate(`/search?query=${query}`)
}
}, [query])
// error
useEffect(() => {
if (error) {
setShowError(true)
setTimeout(() => {
setFadeOut(true)
setTimeout(() => {
setShowError(false)
}, 1000)
}, 5000)
}
}, [error])
return (
<div className='header'>
<Navbar />
<h2 className='header--heading text-center text-light'>Find Images</h2>
<div className='header--form'>
<form onSubmit={handleSubmit}>
<input
className='header--form--input'
autoComplete='off'
type='text'
placeholder='Search'
onChange={handleChange}
name='input'
value={query}
/>
</form>
</div>
{showError && <div className={`network-error ${fadeOut ? 'fade-out' : ''}`}>
<i><FontAwesomeIcon icon={faTriangleExclamation} /></i>
<div className='network-error--message'>
<h5>Network Error</h5>
<p>Please check your Internet connection and try again</p>
</div>
</div>}
</div>
)
}
export default Header
import './App.css';
import Main from './components/Main';
import Search from './components/pages/Search'
import Favorites from './components/pages/Favorites';
import Error from './components/pages/Error';
import { BrowserRouter, Routes, Route } from 'react-router-dom'
import { SkeletonTheme } from 'react-loading-skeleton';
import { useDarkMode } from './components/Navbar';
function App() {
const darkMode = useDarkMode(state => state.darkMode)
let style
if (darkMode === 'light') {
style = 'wrapper'
} else {
style = 'wrapper-dark'
}
return (
<div className={style}>
<SkeletonTheme baseColor="#808080" highlightColor="#b1b1b1">
<BrowserRouter>
<Routes>
<Route path='/' element={<Main />} />
<Route path='search' element={<Search />} />
<Route path='favorites' element={<Favorites />} />
<Route path='*' element={<Error />} />
</Routes>
</BrowserRouter>
</SkeletonTheme>
</div>
);
}
export default App;
1条答案
按热度按时间mzmfm0qo1#
如果我没理解错你的问题,你*不希望在表单域更新时实时更新
query
queryString参数,而是在稍后的某个时候,比如表单提交时,请记住setSeaarchParams
函数的工作原理与navigate
函数类似,但它是对queryString进行操作的。您可以手动更新
searchParams
对象,当表单提交时,调用setSearch
参数而不是navigate
。从input
元素中删除value
属性,因为我们将更新searchParams
对象。