React router: компонент не обновляется при изменении параметра поиска URL

У меня есть приложение React, которое использует URL search params. В зависимости от значения search parameter v компонент должен отображать разный контент.

Возможный URL может выглядеть так:

http://localhost:3000/hello?v=12345

Как только v query parameter изменится в URL, я хочу, чтобы мой компонент обновился.

http://localhost:3000/hello?v=6789

Я использую react-router в своем компоненте приложения для отображения различных компонентов в зависимости от маршрута. Компонент App заключен в компонент BrowserRouter.

render() {
  return (
    <Switch>
      <Route path = "/hello" component = {Hello}></Route>
      <Route path = "/" component = {Home}></Route>
    </Switch>
  );
}

Если пользователь нажимает на что-то и URL search param v изменяется, я хотел бы, чтобы компонент отображал другой контент. В настоящее время URL search param действительно меняется, но компонент больше не отображается. Любые идеи?

Поведение ключевого слова "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) для оценки ваших знаний,...
5
0
4 542
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы не предоставили достаточно информации, поэтому я не могу быть на 100% уверен, где вы ошибаетесь, но я вижу 1 проблему прямо сейчас в вашем коде. Во-первых, вы должны сообщить маршрутизатору, что вы будете использовать параметры. Так, например, ниже код

render() {
  return (
    <Switch>
      <Route path = "/hello/:yourParam" component = {Hello}></Route> // you need the colon here
      <Route path = "/" component = {Home}></Route>
    </Switch>
  );
}

Вышеуказанное сообщит маршруту, что параметр с именем yourParam будет доступен с URL.

Затем он должен быть доступен в вашем компоненте и каким-то образом помещен в функцию рендеринга (используйте его для извлечения данных из базы данных для рендеринга данных, просто визуализируйте параметры напрямую и т. д.).

Например ниже

render(){
    <div>
        {this.props.match.params.yourParam}
    </div>
}

Таким образом, ваш компонент будет повторно отображать каждый раз при изменении параметров.

РЕДАКТИРОВАТЬ

Поскольку вы хотите использовать запрос вместо параметра, вам придется получить его, перейдя. this.props.match.query.v. Вам все равно придется убедиться, что переменная отображается в зависимости от изменения запроса.

Если я сделаю '/ hello /: yourParam', тогда мой URL-адрес будет выглядеть как localhost: 3000 / hello / 123, но я хочу, чтобы он использовал параметры поиска URL, чтобы URL-адрес выглядел как localhost: 3000 / hello? V = 123

productioncoder 04.06.2018 08:20

@slashburn. Извини, моя ошибка. Тогда вам просто нужно будет убедиться, что вы получаете запрос из класса, перейдя на this.props.match.query.v, и убедитесь, что функция рендеринга повторно запускается при изменении этого значения.

forJ 04.06.2018 08:28

Ах я вижу. Спасибо @forJ за то, что указали мне правильное направление

productioncoder 04.06.2018 09:35
Ответ принят как подходящий

Как правильно указал @forJ, основная идея состоит в том, чтобы повторно отрисовать компонент после изменения параметров URL. Я добился этого так:

render() {
  return (
    <Switch>
      <Route path = "/hello" render = {() => (<Hello key = {this.props.location.key}/>)}></Route>
      <Route path = "/" component = {Home}></Route>
    </Switch>
  );
}

this.props.location.key изменяется каждый раз, когда изменяется URL (также при изменении параметров запроса). Таким образом, если вы передадите его в качестве реквизита компоненту, тогда компонент повторно отобразит при изменении параметров URL, даже если base URL (URL без параметров URL) не изменился.

Мне также пришлось использовать компонент высшего порядка withRouter, чтобы он заработал.

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Hello));

withRouter критически важен здесь, если вы используете redux.

Izhaki 12.09.2018 16:27

Использование «ключа» приведет к полному размонтированию и повторному монтированию компонента, поэтому примите во внимание отрицательные последствия для производительности. medium.com/@albertogasparin/…

Chris Bobbe 29.05.2019 19:07

Если вы используете хук useEffect, убедитесь, что у вас есть [props.match.params] вместо пустого массива []

useEffect(() => {

        (async () => {
            // Fetch your data
        })();
    }, [props.match.params]) // <-- By this it will get called when URL changes

конечно для компонентов класса this.props.match.params

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