реагировать на изменения в URL - PullRequest
0 голосов
/ 21 мая 2019

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

Как получить новый идентификатор по ссылке / 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.log(this.state.user)
        return (<div></div>)
    }

Ответы [ 5 ]

1 голос
/ 21 мая 2019

Вы будете использовать Компонент ProfileUser как этот

< ProfileUser
{...props}
/>

pass ID и KEY в этом компоненте как этот

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

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

маршрутизатор будет выглядеть следующим образом

<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

1 голос
/ 21 мая 2019

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

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

1 голос
/ 21 мая 2019

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

if (nextProps.match.params.id !== this.props.match.params.id) {
    this.props.getUserById(nextProps.props.match.params.id);
}
0 голосов
/ 21 мая 2019

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

componentWillReceiveProps(nextProps) {

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

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

      }
0 голосов
/ 21 мая 2019

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

...