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]);