Функция setState не присваивает логическое значение .. почему? - PullRequest
0 голосов
/ 20 мая 2019

Я новичок в реакции на родную, и я не смог понять это поведение.в асинхронной функции я устанавливаю логическое значение загрузки до состояния перед вызовом API.Теперь, что странно: после получения ответа я не могу установить загрузочный логический параметр обратно в false.он просто ждет в функции setState, не достигая обратного вызова.

Я уже пытался установить setState в нескольких вызовах для каждого значения.или все в одном вызове функции.я также попытался назначить весь ответ государству.в реагировать родной я могу консоль журнала ответ после извлечения его из бэкэнда формы.Также я могу назначить ответ на состояние при выходе из логического загрузки загрузки (достижение обратного вызова) .. однако не при попытке установить логическое значение загрузки обратно в ложь.подсказка (возможно): в ответе json я включаю массив.при выходе из массива (не присваивая его состоянию) он ведет себя так, как должен ... пожалуйста, помогите!

// here my mistery
export default class App extends React.Component {  
 constructor(props) {
  super(props);
 this.state = {
  loading: false,   
}
}

async onLogin() {
try {

  this.setState({ loading: true }, function () {
    console.log('loading is:' + this.state.loading)
  }); //works great

  const { name, password } = this.state;

  //here the api call
  const response = 
 await fetch(`http://10.0.2.2:3000/api/login/${name}&${password}`);
  const answer = await response.json();

  if (answer.user == 'OK') {

    //now the strange function-call
    this.setState({
      tickets: answer.tickets, //this is the array..!
      title: answer.event.title,
      token: answer.token.token,
      tokenDa: true,
      //loading: false, //only reaching callback when commenting that out
    }, function () {
      console.log('tickets are :' + this.state.tickets[0].kategorie)
    })

    // same behaviour here 
    // this.setState({loading: false},  function(){
    //   console.log('loading ist ' + this.state.loading);
    // });
  }
}
catch{
  console.log('in CATCH ERROR')
}
}

// here also the render function in case that matters:
render() {
if (this.state.loading) {
  return (
    <View style={styles.container}>
      <ActivityIndicator size='large' />
    </View>
  );
}

return this.state.tokenDa ? (
  <View style={styles.container}>
    <Text>Event Title : {this.state.title} </Text>


    <Button
      title={'scan'}
      style={styles.input} 

    />
    {this.state.tickets.map((ticket, i) => (
      <div key={i}>
        <Text >TicketKategorie : {ticket.kategorie}</Text>
        <Text > Datum und Türöffnung {ticket.gueltig_am}</Text>
        <Text >Verkauft {ticket.verkauft}</Text>
        <Text >Eingescannt {ticket.abbgebucht}</Text>
      </div>
    ))}
  </View>
) : (
    <View style={styles.container}>

      <TextInput
        value={this.state.name}
        onChangeText={(name) => this.setState({ name })}
        placeholder={'Username'}
        style={styles.input}
      />
      <TextInput
        value={this.state.password}
        onChangeText={(password) => this.setState({ password })}
        placeholder={'Password'}
        secureTextEntry={true}
        style={styles.input}
      />

      <Button
        title={'Login'}
        style={styles.input}
        onPress={this.onLogin.bind(this)}
      />
    </View>

  )
};
};

результат: экран загрузки из-за атрибута загрузки, для которого я не могу установить значение false.почему это происходит!?

Ответы [ 2 ]

0 голосов
/ 20 мая 2019

Вам нужно обернуть оставшуюся часть кода в обратный вызов для первого setState, как это ...

this.setState({ loading: true }, async function () {
  const { name, password } = this.state;
  const response = 
 await fetch(`http://10.0.2.2:3000/api/login/${name}&${password}`);
  const answer = response.json();

  if (answer.user == 'OK') {
    this.setState({
      tickets: answer.tickets, //this is the array..!
      title: answer.event.title,
      token: answer.token.token,
      tokenDa: true,
      loading: false
    });
  }
});
0 голосов
/ 20 мая 2019

Как вы, возможно, уже поняли, существует проблема с асинхронной природой ваших setStates.Чтобы обойти это, мы можем создать другую функцию для обработки фактического запроса API и использовать ее в обратном вызове для первого установленного состояния.

setLoading = () => {
    this.setState({ loading: true }, () => this.onLogin())
}

onLogin = async () => {
  const { name, password } = this.state;

  //here the api call
  const response = await fetch(`http://10.0.2.2:3000/api/login/${name}&${password}`);
  const answer = await response.json();

  if (answer.user == 'OK') {
    this.setState({
      tickets: answer.ticketsm
      title: answer.event.title,
      token: answer.token.token,
      tokenDa: true,
      loading: false
    }, function () {
      console.log('tickets are :' + this.state.tickets[0].kategorie)
    })
}
...