Как я могу предотвратить запуск componentDidMount до того, как мой вызов веб-службы завершится - PullRequest
0 голосов
/ 02 марта 2019

Когда приложение запускается, появляется SplashScreen.За splashScreen я хочу получить имя пользователя и пароль из кэша, а затем вызвать веб-сервис.Но когда я получаю данные из кеша, например AsyncStorage.getItem('myKey'), который находится в componentWillMount, он начинает рендеринг.Это не позволяет componentWillMount закончить.

Моя большая проблема в том, что componentDidMount запускается до того, как мои controlallMeth методы заканчиваются.Из-за этого приложение вылетает в такой ситуации.Как я могу решить эту проблему?
Вот мой код:

Я получаю имя пользователя и пароль из кэша приложения и вызываю веб-службу следующим образом:

 componentWillMount(){
      AsyncStorage.getItem('myKey').then(value => {
        let valuePrsed = JSON.parse(value);
        if(valuePrsed.username != null && valuePrsed.password != null)
        {
            this.setState({username: valuePrsed.username, password: valuePrsed.password});
            this.controlallMeth(); // call webservice
        }
      })
    }

Вот метод, где я вызываю веб-сервис:

controlallMeth(){
        let collection={}
        collection.username = this.state.username,
        collection.password = this.state.password

        fetch('url', {
            method: 'POST',
            headers: new Headers({
                          Accept: 'application/json',
                        'Content-Type': 'application/json', // <-- Specifying the Content-Type
                }),
            body: JSON.stringify(collection) // <-- Post parameters
            })
            .then((response) => response.text())
            .then(leaders => {

                    this.setState({PersonalInfo: leaders});

            })
            .catch((error) => {
                console.error(error);
            });
    }

А вот componentDidMount

 componentDidMount() {

      StatusBar.setHidden(true);
        this.setState({ fadeAnim: new Animated.Value(0) },
        () => {
          Animated.timing(          // Animate over time
            this.state.fadeAnim, // The animated value to drive
            {
              toValue: 1,           // Animate to opacity: 1 (opaque)
              duration: 3000,
            }
          ).start(() => {
              if(this.state.values != null)
              {
                console.log("go page1");
                  this.props.navigation.navigate('Page1',{datas: this.state.PersonalInfo});
              }
              else{
                this.props.navigation.navigate('login');
              }
          })
        })              // Starts the animation
    }

Ответы [ 2 ]

0 голосов
/ 02 марта 2019

Учитывая, что componentWillMount устарела, лучше не использовать его.Вы можете получить свои кэшированные значения внутри constructor или componentDidMount метода

constructor(props) {
  super(props);

  StatusBar.setHidden(true);

  AsyncStorage.getItem('myKey').then(value => {
    let valuePrsed = JSON.parse(value);
    if(valuePrsed.username != null && valuePrsed.password != null)
    {
      this.setState({username: valuePrsed.username, password: valuePrsed.password});
      this.controlAllMeth(); // call webservice
    }
  });
}

Чтобы убедиться, что метод анимации и выборки полностью завершен, прежде чем перейти на другой экран, вы можете использовать Promise.all:

controlAllMeth() {
  Promise.all([this.callFetch(), this.startAnim()])
    .then(([fetchResponse, animResponse]) => {
      this.setState({PersonalInfo: fetchResponse.text()});

      if(this.state.values != null)
      {
        console.log("go page1");
        this.props.navigation.navigate('Page1',{datas: this.state.PersonalInfo});
      }
      else{
        this.props.navigation.navigate('login');
      }
    })
    .catch(err => {

    });
}

callFetch() {
  let collection={}
  collection.username = this.state.username,
  collection.password = this.state.password

  return fetch(url, {
    method: 'POST',
    headers: new Headers({
      Accept: 'application/json',
      'Content-Type': 'application/json', // <-- Specifying the Content-Type
    }),
    body: JSON.stringify(collection) // <-- Post parameters
    }
  );
}

startAnim() {
  return new Promise((resolve, reject) => {
    this.setState({ fadeAnim: new Animated.Value(0) },
      () => {
        Animated.timing(          // Animate over time
          this.state.fadeAnim, // The animated value to drive
          {
            toValue: 1,           // Animate to opacity: 1 (opaque)
            duration: 3000,
          }
        ).start(() => {
          resolve();
        })
      });              // Starts the animation  
  });
}
0 голосов
/ 02 марта 2019

Вы можете использовать здесь асинхронный метод, как controlallMeth асинхронный вызов.Заставить весь процесс ждать, убедившись, что вы выполняете запрос на выборку, затем двигаться дальше.

async componentWillMount(){
      AsyncStorage.getItem('myKey').then(value => {
        let valuePrsed = JSON.parse(value);
        if(valuePrsed.username != null && valuePrsed.password != null)
        {
            this.setState({username: valuePrsed.username, password: valuePrsed.password});
          await this.controlallMeth(); //I am assuming you did a typo here this.controlall();
        }
      })
    }
 controlallMeth = async() => {
        let collection={}
        collection.username = this.state.username,
        collection.password = this.state.password

        const res = await fetch('url', {
            method: 'POST',
            headers: new Headers({
                          Accept: 'application/json',
                        'Content-Type': 'application/json', // <-- Specifying the Content-Type
                }),
            body: JSON.stringify(collection) // <-- Post parameters
            })
            const leaders = await res.text();
            this.setState({PersonalInfo: leaders});
    }

Хотя не рекомендуется использовать асинхронные вызовы в componentWillMount, так что вы можете переключиться на componentDidMount

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...