Почему я получаю "http://localhost:3000/?" route при использовании useNavigate в реакции?

Я использую useNavigate для перехода с одной страницы моего веб-сайта на другую при нажатии кнопки. Когда я запускаю сайт с помощью npm start, когда я нажимаю кнопку, страница перезагружает текущую страницу, а URL-адрес изменяется с «http://localhost:3000» на «http://localhost:3000/?».

Код ниже:

const submitForm = async (e) => {
const res = await fetch("http://localhost:8000/properties")
const jsonData = await res.json()
setProperties(jsonData)
navigate("/list", { state: properties })
}

элемент кнопки:

<button onClick={() => submitForm()}>Find Properties</button>

Для настройки моих маршрутов в App.js у меня просто есть:

export default function App() {
  return (
    <BrowserRouter>
      <div className="App">
        <Routes>
          <Route exact path="/" element={<FormComponent />} />
          <Route path="/list" element={<ListComponent />} />
        </Routes>
      </div>
    </BrowserRouter>
  )
}

у вас есть какие-либо проблемы? или вы спрашиваете просто из любопытства

Daniel Cruz 20.11.2022 03:35

Я думаю, вы можете захотеть предотвратить отправку по умолчанию.... e.preventDefault()

KcH 20.11.2022 04:15

<button type='button', чтобы кнопка не отправляла форму. Лучше, чем отправить и предотвратить отправку...

Niels Lucas 22.11.2022 11:33
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Если вы веб-разработчик (или хотите им стать), то вы наверняка гик и вам нравятся "Звездные войны". А как бы вы хотели, чтобы фоном для вашего...
учебник по Javascript
учебник по Javascript
JavaScript - это язык программирования, который обычно используется для добавления интерактивности и других динамических функций на веб-сайты. Он...
Как использовать d3.js для рисования 2D SVG-элементов в приложении Angular?
Как использовать d3.js для рисования 2D SVG-элементов в приложении Angular?
D3.js - это обширная библиотека, используемая для привязки произвольных данных к объектной модели документа (DOM). Мы разберем основные варианты...
Освоение принципов SOLID в JavaScript: Пошаговое руководство
Освоение принципов SOLID в JavaScript: Пошаговое руководство
Принцип единой ответственности (SRP): класс должен иметь только одну причину для изменения. Другими словами, у него должна быть только одна...
JavaScript - For Loop
JavaScript - For Loop
Наиболее используемая компактная форма оператора цикла.
Неделя 1 - Карточки с временной шкалой
Неделя 1 - Карточки с временной шкалой
Поскольку это была первая неделя, я решил начать с простого. Предполагалось, что у меня будет временная шкала с несколькими карточками, которые можно...
1
3
71
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

вопросы

  1. Похоже, что эта кнопка, скорее всего, отображается внутри элемента form, и когда форма отправляется, действие формы по умолчанию не предотвращается, и страница перезагружается.

  2. Кроме того, похоже, что обработчик submitForm ставит в очередь обновление состояния React, а затем пытается перейти к ожидаемому обновленному состоянию.

    const submitForm = async (e) => {
      const res = await fetch("http://localhost:8000/properties");
      const jsonData = await res.json();
      setProperties(jsonData);                  // <-- enqueued state update
      navigate("/list", { state: properties }); // <-- stale state
    }
    

    В React обновления состояния в очереди обрабатываются асинхронно. Вы не можете поставить в очередь обновление состояния и ожидать, что обновленное значение состояния будет прочитано в той же области функции/обратного вызова, в которой обновление было поставлено в очередь.

  3. Элементы button имеют type="submit" по умолчанию, если атрибут type не указан.

Решение

  1. Переместите обработчик обратного вызова submitForm в свойство обработчика form элемента onSubmit.
  2. Вызовите preventDefault на объекте события onSubmit.
  3. Явно объявите тип кнопки.
  4. Передайте полученные данные JSON непосредственно в функцию navigate, нет необходимости обновлять локальное состояние, учитывая, что компонент, скорее всего, скоро будет размонтирован.

Пример:

const submitForm = async (e) => {
  e.preventDefault(); // <-- prevent default form action

  const res = await fetch("http://localhost:8000/properties");
  const jsonData = await res.json();

  navigate("/list", { state: jsonData }); // <-- pass current data
}

...

<form onSubmit={submitForm}>
  ...

  <button type="submit">Find Properties</button>
  ...
</form>

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