Я пытаюсь реализовать нумерацию страниц на маршруте с помощью react-router и react-router-bootstrap. Проблема в том, что я использую LinkContainers, которые должны отображать один и тот же маршрут с другим параметром поиска, который содержит «страницу», на которую я перехожу, но когда я нажимаю на нее, он просто обновляет адресную строку в браузере. t перерисовать маршрут.
{"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"
}}
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>
)
}
(большинство из этого)
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.info(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
... пагинация - это отдельный компонент
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
Прямо сейчас, когда вы нажимаете любую из ссылок «разбивка на страницы», она обновляет адресную строку в браузере следующим образом:
http://localhost:3000/ -> http://localhost:3000/?page=2 -> http://localhost:3000/?page= и т.д...
Но он не обновляет содержимое страницы, и консоль не показывает никаких ошибок/предупреждений.
Однако я могу выбрать URL-адрес (например, http://localhost:3000/?page=2) и нажать ввод вручную в адресной строке браузера, после чего он отобразит нужную страницу.
Я подозреваю, что это как-то связано со ссылками, находящимися в отдельном компоненте, я думаю, что можно создать функцию в CompanyDirScreen.jsx, которая «переходит» на запрошенную страницу и передает ее в качестве реквизита Paginate.jsx, хотя это выглядит немного запутанно , другой вариант — сделать разбивку на страницы непосредственно в CompanyDirScreen.jsx, но тогда я не смогу повторно использовать компонент в других маршрутах, которые я планирую.
Есть ли способ использовать LinkContainer для навигации между страницами, как описано?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Хук useEffect в CompanyDirScreen использует пустой массив зависимостей, поэтому эффект запускается только один раз при монтировании компонента. Вот почему URL-адрес работает, когда вы вручную вводите его в адресную строку.
Добавьте keywords в массив зависимостей, чтобы при обновлении значения параметра поиска обратный вызов хука useEffect срабатывал снова.
// Location info to determine the page to jump to
const { search: keywords } = useLocation();
useEffect(() => {
console.info(keywords);
getCompanies(keywords);
}, [keywords]);