LinkContainer реакции-маршрутизатора-загрузки не перенаправляет/не обновляет при нажатии

Я пытаюсь реализовать нумерацию страниц на маршруте с помощью 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"
  }}

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.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

... пагинация - это отдельный компонент

Разбиение на страницы.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

Прямо сейчас, когда вы нажимаете любую из ссылок «разбивка на страницы», она обновляет адресную строку в браузере следующим образом: 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 для навигации между страницами, как описано?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
24
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Хук 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]);

Другие вопросы по теме