Асинхронная функция в React не имеет доступа к этому

avatar
Evanss
8 апреля 2018 в 05:01
1460
1
1

Я использую React с клиентом Apollo. Когда пользователь входит в систему, мне нужно обновить запрос USER, чтобы я мог решить, куда его перенаправить, исходя из того, какие поля присутствуют в его профиле.

Мой код зависает на этой строке:

await this.props.USER.refetch();

Я думаю, это связано с тем, что выполнение асинхронной функции изменяет контекст this.

async login() {

  const result = await this.props.LoginMutation({
    variables: {
      email: this.state.email,
      password: this.state.password,
    },
  });

  const token = await result.data.authenticateUser.token;

  await this._saveUserData(token);

  // This is where the code hangs 
  await this.props.USER.refetch();


  // If no user profile pic has been set then redirect to the account page
  if (!this.props.USER.user.profilePic) {
    this.setState({
      redirect: '/account',
    });
  }

  // If no location is set redirect to the homepage
  if (!this.props.USER.user.location) {
    this.setState({
      redirect: '/',
    });
  }

  if (this.props.USER.user.location) {
    this.setState({
      redirect: `/${this.props.USER.user.location.machineName}`,
    });
  }

  this.setState({
    redirect: `/`,
  });
}

Инструменты разработчика React показывают мне, что this.props.USER.refetch() действительно существует:

enter image description here

Источник

Ответы (1)

avatar
Shubham Khatri
8 апреля 2018 в 05:22
1

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

.
login = async () => {

  const result = await this.props.LoginMutation({
    variables: {
      email: this.state.email,
      password: this.state.password,
    },
  });

  const token = await result.data.authenticateUser.token;

  await this._saveUserData(token);

  // This is where the code hangs 
  await this.props.USER.refetch();


  // If no user profile pic has been set then redirect to the account page
  if (!this.props.USER.user.profilePic) {
    this.setState({
      redirect: '/account',
    });
  }

  // If no location is set redirect to the homepage
  if (!this.props.USER.user.location) {
    this.setState({
      redirect: '/',
    });
  }

  if (this.props.USER.user.location) {
    this.setState({
      redirect: `/${this.props.USER.user.location.machineName}`,
    });
  }

  this.setState({
    redirect: `/`,
  });
}
Evanss
8 апреля 2018 в 05:39
0

Мой код все еще висит на том же месте. Инструменты React dev показывают мне, что функция существует (см. Обновление моего вопроса), так что может ли это быть конкретной проблемой Apollo, а не Rect?

Evanss
8 апреля 2018 в 06:37
0

Выяснилось, что это проблема Аполлона. Я создал новый компонент, у которого есть собственная страница, и обновил запросы в componentDidMount. Теперь он работает.