react-router-bootstrap LinkContainer 不是 redirecting/refreshing 点击
react-router-bootstrap LinkContainer not redirecting/refreshing on click
我正在尝试使用 react-router 和 react-router-bootstrap 在路由上实现分页。问题是我使用的 LinkContainers 应该使用包含我要跳转到的 'page' 的不同搜索参数呈现相同的路由,但是当我单击它时,它只会更新浏览器芽中的地址栏不会重新渲染路线。
设置:
{"dependencies": {
"axios": "^0.26.0",
"bootstrap": "^5.1.3",
"react": "^17.0.2",
"react-bootstrap": "^2.2.0",
"react-dom": "^17.0.2",
"react-router-bootstrap": "^0.26.0",
"react-router-dom": "^6.2.2",
"react-scripts": "5.0.0",
"web-vitals": "^2.1.4"
}}
App.js:
import { Container } from 'react-bootstrap'
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'
import CompanyCreateScreen from './screens/CompanyCreateScreen'
import CompanyDirScreen from './screens/CompanyDirScreen'
function App() {
return (
<Router>
<main className="py-3">
<Container className="cont-width">
<Routes>
<Route path="/" exact element={<CompanyDirScreen />} />
<Route path="/new_company" element={<CompanyCreateScreen />} />
</Routes>
</Container>
</main>
</Router>
)
}
CompanyDirScreen.jsx :
(大部分)
import React, { useEffect, useState } from 'react'
import { useLocation } from 'react-router-dom'
import { LinkContainer } from 'react-router-bootstrap'
import { Row, Col, Button } from 'react-bootstrap'
import UniContainer from '../components/UniContainer'
import Loader from '../components/Loader'
import Message from '../components/Message'
import CompanyList from '../components/CompanyList'
import Paginate from '../components/Paginate'
import axios from 'axios'
const API_URL = 'http://localhost:8000/api'
const CompanyDirScreen = () => {
const [companies, setCompanies] = useState({})
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
const [page, setPage] = useState(0)
const [pages, setPages] = useState(0)
// Location info to determine the page to jump to
const location = useLocation()
let keywords = location.search
useEffect(() => {
console.log(keywords)
getCompanies((keywords = keywords))
}, [])
// Get companies
const getCompanies = async (keywords = '') => {
setLoading(true)
try {
const { data } = await axios.get(`${API_URL}/companies/${keywords}`)
setCompanies(data.companies)
setPage(data.page)
setPages(data.pages)
} catch (error) {
const e =
error.response && error.response.data.detail
? error.response.data.detail
: error.message
setError(e)
}
setLoading(false)
}
// Delete single company
const deleteCompany = async (id) => {
}
return (
<UniContainer>
<Row className="mb-3">
<Col>
<h3>Directorio de empresas</h3>
</Col>
<Col xs={3}>
<LinkContainer to="/new_company">
<Button>Nueva empresa</Button>
</LinkContainer>
</Col>
</Row>
{loading ? (
<Loader />
) : error ? (
<Message variant="danger">{error}</Message>
) : companies.length === 0 ? (
<Message variant="secondary">
Aun no hay empresas registradas, se el primero haciendo click en{' '}
<b>"Añadir empresa"</b>
</Message>
) : (
<>
<CompanyList companies={companies} handleDelete={deleteCompany} />
<Paginate page={page} pages={pages} />
</>
)}
</UniContainer>
)
}
export default CompanyDirScreen
...分页是一个单独的组件
Paginate.jsx
import { Pagination } from 'react-bootstrap'
import { LinkContainer } from 'react-router-bootstrap'
const Paginate = ({ pages, page }) => {
return (
pages > 1 && (
<Pagination className="justify-content-center">
{page > 1 && (
<LinkContainer to={`/?page=${page - 1}`}>
<Pagination.Prev />
</LinkContainer>
)}
{[...Array(pages).keys()].map((x) => (
<LinkContainer key={x + 1} to={`/?page=${x + 1}`}>
<Pagination.Item active={x + 1 === page}>{x + 1}</Pagination.Item>
</LinkContainer>
))}
{page !== pages && (
<LinkContainer to={`/?page=${page + 1}`}>
<Pagination.Next />
</LinkContainer>
)}
</Pagination>
)
)
}
export default Paginate
现在,当单击任何 'pagination' 链接时,它会像这样更新浏览器中的地址栏:
http://localhost:3000/
-> http://localhost:3000/?page=2
-> http://localhost:3000/?page=
等...
但它不会更新页面内容,控制台也不会显示任何内容 errors/warnings。
不过,我可以 select url(例如 http://localhost:3000/?page=2
)并在浏览器地址栏中手动按下回车键,然后它会呈现所需的页面。
我怀疑它与链接在一个单独的组件中有关,我认为可以在 CompanyDirScreen.jsx
中创建一个函数 'navigates' 到请求的页面并将其传递作为 Paginate.jsx
的道具,虽然感觉有点乱,但另一种选择是直接在 CompanyDirScreen.jsx
中进行分页,但那样我就无法在我计划的其他路线中重用该组件.
有没有一种方法可以使用 LinkContainer 在页面之间导航?
CompanyDirScreen
中的useEffect
钩子使用了一个空的依赖数组,所以效果是运行组件挂载时只有一次。这就是当您在地址栏中手动输入 URL 时它起作用的原因。
将keywords
添加到依赖数组,这样当搜索参数值更新时,useEffect
挂钩回调将再次触发。
// Location info to determine the page to jump to
const { search: keywords } = useLocation();
useEffect(() => {
console.log(keywords);
getCompanies(keywords);
}, [keywords]);
我正在尝试使用 react-router 和 react-router-bootstrap 在路由上实现分页。问题是我使用的 LinkContainers 应该使用包含我要跳转到的 'page' 的不同搜索参数呈现相同的路由,但是当我单击它时,它只会更新浏览器芽中的地址栏不会重新渲染路线。
设置:
{"dependencies": {
"axios": "^0.26.0",
"bootstrap": "^5.1.3",
"react": "^17.0.2",
"react-bootstrap": "^2.2.0",
"react-dom": "^17.0.2",
"react-router-bootstrap": "^0.26.0",
"react-router-dom": "^6.2.2",
"react-scripts": "5.0.0",
"web-vitals": "^2.1.4"
}}
App.js:
import { Container } from 'react-bootstrap'
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'
import CompanyCreateScreen from './screens/CompanyCreateScreen'
import CompanyDirScreen from './screens/CompanyDirScreen'
function App() {
return (
<Router>
<main className="py-3">
<Container className="cont-width">
<Routes>
<Route path="/" exact element={<CompanyDirScreen />} />
<Route path="/new_company" element={<CompanyCreateScreen />} />
</Routes>
</Container>
</main>
</Router>
)
}
CompanyDirScreen.jsx :
(大部分)
import React, { useEffect, useState } from 'react'
import { useLocation } from 'react-router-dom'
import { LinkContainer } from 'react-router-bootstrap'
import { Row, Col, Button } from 'react-bootstrap'
import UniContainer from '../components/UniContainer'
import Loader from '../components/Loader'
import Message from '../components/Message'
import CompanyList from '../components/CompanyList'
import Paginate from '../components/Paginate'
import axios from 'axios'
const API_URL = 'http://localhost:8000/api'
const CompanyDirScreen = () => {
const [companies, setCompanies] = useState({})
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
const [page, setPage] = useState(0)
const [pages, setPages] = useState(0)
// Location info to determine the page to jump to
const location = useLocation()
let keywords = location.search
useEffect(() => {
console.log(keywords)
getCompanies((keywords = keywords))
}, [])
// Get companies
const getCompanies = async (keywords = '') => {
setLoading(true)
try {
const { data } = await axios.get(`${API_URL}/companies/${keywords}`)
setCompanies(data.companies)
setPage(data.page)
setPages(data.pages)
} catch (error) {
const e =
error.response && error.response.data.detail
? error.response.data.detail
: error.message
setError(e)
}
setLoading(false)
}
// Delete single company
const deleteCompany = async (id) => {
}
return (
<UniContainer>
<Row className="mb-3">
<Col>
<h3>Directorio de empresas</h3>
</Col>
<Col xs={3}>
<LinkContainer to="/new_company">
<Button>Nueva empresa</Button>
</LinkContainer>
</Col>
</Row>
{loading ? (
<Loader />
) : error ? (
<Message variant="danger">{error}</Message>
) : companies.length === 0 ? (
<Message variant="secondary">
Aun no hay empresas registradas, se el primero haciendo click en{' '}
<b>"Añadir empresa"</b>
</Message>
) : (
<>
<CompanyList companies={companies} handleDelete={deleteCompany} />
<Paginate page={page} pages={pages} />
</>
)}
</UniContainer>
)
}
export default CompanyDirScreen
...分页是一个单独的组件
Paginate.jsx
import { Pagination } from 'react-bootstrap'
import { LinkContainer } from 'react-router-bootstrap'
const Paginate = ({ pages, page }) => {
return (
pages > 1 && (
<Pagination className="justify-content-center">
{page > 1 && (
<LinkContainer to={`/?page=${page - 1}`}>
<Pagination.Prev />
</LinkContainer>
)}
{[...Array(pages).keys()].map((x) => (
<LinkContainer key={x + 1} to={`/?page=${x + 1}`}>
<Pagination.Item active={x + 1 === page}>{x + 1}</Pagination.Item>
</LinkContainer>
))}
{page !== pages && (
<LinkContainer to={`/?page=${page + 1}`}>
<Pagination.Next />
</LinkContainer>
)}
</Pagination>
)
)
}
export default Paginate
现在,当单击任何 'pagination' 链接时,它会像这样更新浏览器中的地址栏:
http://localhost:3000/
-> http://localhost:3000/?page=2
-> http://localhost:3000/?page=
等...
但它不会更新页面内容,控制台也不会显示任何内容 errors/warnings。
不过,我可以 select url(例如 http://localhost:3000/?page=2
)并在浏览器地址栏中手动按下回车键,然后它会呈现所需的页面。
我怀疑它与链接在一个单独的组件中有关,我认为可以在 CompanyDirScreen.jsx
中创建一个函数 'navigates' 到请求的页面并将其传递作为 Paginate.jsx
的道具,虽然感觉有点乱,但另一种选择是直接在 CompanyDirScreen.jsx
中进行分页,但那样我就无法在我计划的其他路线中重用该组件.
有没有一种方法可以使用 LinkContainer 在页面之间导航?
CompanyDirScreen
中的useEffect
钩子使用了一个空的依赖数组,所以效果是运行组件挂载时只有一次。这就是当您在地址栏中手动输入 URL 时它起作用的原因。
将keywords
添加到依赖数组,这样当搜索参数值更新时,useEffect
挂钩回调将再次触发。
// Location info to determine the page to jump to
const { search: keywords } = useLocation();
useEffect(() => {
console.log(keywords);
getCompanies(keywords);
}, [keywords]);