Бесконечный цикл при отправке в componentWillReceiveProps

У меня есть компонент профиля, который загружается реактивным маршрутизатором (path = "profile/: username" ), и сам компонент выглядит следующим образом:

...
import { fetchUser } from '../actions/user';

class Profile extends Component {
  constructor(props) {
    super(props);
  }
  componentDidMount() {
    const { username } = this.props;
    this.fetchUser(username);
  }
  componentWillReceiveProps(nextProps) {
    const { username } = nextProps.params;
    this.fetchUser(username);
  }
  fetchUser(username) {
    const { dispatch } = this.props;
    dispatch(fetchUser(username));
  }
  render() {...}
}

export default connect((state, ownProps) => {
  return {
    username: ownProps.params.username,
    isAuthenticated: state.auth.isAuthenticated
  };
})(Profile);

И действие fetchUser выглядит так (redux-api-middleware):

function fetchUser(id) {
  let token = localStorage.getItem('jwt');
  return {
    [CALL_API]: {
      endpoint: `http://localhost:3000/api/users/${id}`,
      method: 'GET',
      headers: { 'x-access-token': token },
      types: [FETCH_USER_REQUEST, FETCH_USER_SUCCESS, FETCH_USER_FAILURE]
    }
  }
}

Причина, по которой я добавил функцию componentWillReceiveProps, - это отреагировать, когда URL-адрес изменится на другое: имя пользователя и загрузить эту информацию о профиле пользователя. На первый взгляд все, кажется, работает, но затем я заметил, что при отладке функция componentWillReceiveProps вызывается в бесконечном цикле, и я не знаю почему. Если я удалю компонент componentWillReceiveProps, тогда профиль не будет обновляться с новым именем пользователя, но тогда у меня нет проблемы с петлями. Любые идеи?

Ответ 1

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

Добавьте сравнение, чтобы проверить, не изменяется ли конкретная поддержка: fooobar.com/questions/502149/...

Ответ 2

Попробуйте добавить условие для сравнения реквизита. Если ваш компонент нуждается в этом.

componentWillRecieveProps(nextProps){
 if(nextProps.value !== this.props.value)
  dispatch(action()) //do dispatch here 
}

Ответ 3

Если вы реагируете на маршруты с некоторыми параметрами пути, такими как profile/: username, Вы можете просто сравнить props.location.pathname

componentWillReceiveProps(nextProps){    
    if(nextProps.location.pathname !== this.props.location.pathname){
          dispatch()
        }
 }