Реагировать на изменение URL-адреса

Я получаю профиль пользователя по ID. Но когда я пытаюсь зайти на страницу другого пользователя по ссылке с той же страницы, я не могу поймать новый ID из URL. Он ловится в методе componentWillReceiveProps, но я не могу вызвать из него запрос к базе данных для получения данных по ID, потому что возникает бесконечный цикл.

Как мне получить новый ID по ссылке /profile/5cc6c0e743d02ff2860d8f20, чтобы компонент обновился и я смог получить данные из базы данных и вставить их в компонент?

на самом деле мне нужно получить реквизиты из props.match.params.id и передать их в this.props.getUserById (this.props.match.params.id), в то время как props.match.params.id доступен только в метод componentWillReceiveProps

class ProfileUser extends Component {    
    state = {
        user: {}
    };

    componentDidMount() {
        // When first time i load component it works fine, i call database and get info
        this.props.getUserById(this.props.match.params.id);
    }

    componentWillReceiveProps(nextProps) {
        // Here I get user information
        this.setState({user: nextProps.profile.user})
        // when I switch to another page with another ID this.props.match.params.id, this method works but I can't call this.props.getUserById(this.props.match.params.id); from here because an infinite loop appears
        // this.props.getUserById(this.props.match.params.id);
    }

    render() {
        console.info(this.state.user)
        return (<div></div>)
    }
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
0
812
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

1- установить идентификатор как переменную состояния 2- в компоненте будет получена проверка реквизитов, если nextProps.match.params.id совпадает с идентификатором, который мы установили на шаге 1, если да, не делайте сетевой вызов, иначе снова установите идентификатор и сделайте сетевой вызов

Сравните, старые и новые свойства получают пользователя только тогда, когда компонент делает что-либо с новый реквизит

componentWillReceiveProps(nextProps) {

    if (nextProps.match.params.id !== this.props.match.params.id ) {

        this.props.getUserById(this.props.match.params.id);

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

Перезагружайте пользователя только при изменении идентификатора:

if (nextProps.match.params.id !== this.props.match.params.id) {
    this.props.getUserById(nextProps.props.match.params.id);
}

Причина получения бесконечного цикла

Вы получаете бесконечный цикл, потому что componentWillReceiveProps вызывается всякий раз, когда изменяется реквизит, поэтому при такой функции, если вы напишете эту строку this.props.getUserById(this.props.match.params.id), она извлечет информацию старого пользователя (скажем, пользователя A), потому что this.props относится к старым реквизитам, а nextProps относится к новым (давайте скажем, пользователь B), следовательно, вы снова пользователь A. В этот момент nextProps ссылается на пользователя A, а this.props ссылается на пользователя B. Итак, props меняется, он снова выбирает пользователя B, и вы получаете бесконечный цикл .

Решение

Извлекать пользователя только в том случае, если оба идентификатора разные и пользователь nextProps.props.match.params.id вместо this.props.

if (nextProps.match.params.id !== this.props.match.params.id) {
    this.props.getUserById(nextProps.props.match.params.id);
}

Улучшения

Я рекомендовал вам использовать хуки вместо компонентов на основе классов для всех новых компонентов, которые вы создаете. Это делает вещи более простыми. См. документацию для хука useEffect, вы упомянете в нем аргументы, которые извлекают пользователя только в том случае, если что-то от пользователя изменяется. так что только одна вещь будет делать работу для componentDidMount и ComponentWillReceiveProps

Вы будете использовать компонент ProfileUser следующим образом:

< ProfileUser
{...props}
/>

передайте ID и KEY в этом компоненте, как это

< ProfileUser
key = {this.props.match.params.id}
id = {this.props.match.params.id}
{...props}
/>

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

роутер будет выглядеть так

<Route
  exact
  path = "/something/:id"
  render = {(props)=> (
    <ProfileUser
      key = {props.match.params.id}
      id = {props.match.params.id}
      {...props}
    />
  )}
/>

для получения дополнительной информации об этом -- перейдите по этой ссылке - https://dev.to/ganderzz/react-controlling-rendering-through-keys-274m

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