2017-09-19 1 views
0

J'ai une entrée:essayant de ne pas obtenir la réponse d'un changement de dernière minute

input field

onChange de la valeur de cette entrée de mise à jour et get stockées dans des accessoires pour persistence mais c'est sans rapport avec la question.

Je vais ajouter une coche à côté du champ si la valeur entrée est trouvée dans la base de données.

J'ai déjà l'appel à l'API et répondre à mettre en place (mon réducteur redux).

import EventTypes from '../EventTypes'; 

const initialState = { 
    response: {}, 
}; 

export default (state = initialState, action) => { 
    switch (action.type) { 
     case EventTypes.EXISTS_FULFILLED.type: 
      console.log(action.payload.body().data()); 
      return { ...state, response: action.payload.body().data() }; 
     default: 
      return state; 
    } 
}; 

Notez que le journal de la console ci-dessus affiche correctement la valeur true/false (+ valeur envoyé je reçois deux retour du serveur).

mais dans le composant qui appelle ceci:

const defaultProps = { 
    onChange:() => { 
    }, 
    value: { type: '' }, 
    provider: { type: '' }, 
}; 

class InputsComponent extends Component { 

    onChange =() => { 
     this.props.onChange(this.props.id); 
    }; 

    updateFirstInput(event) { 
      const { onChange, exists, response } = this.props; 
      const payload = { 
       objectType: this.props.placeholder.toLowerCase(), 
       objectName: event.target.value, 
      }; 
      exists(payload); 
      this.setState({ firstInput: event.target.value }); 
      onChange({ value: { 
       ...this.state, 
       firstInput: event.target.value, 
      } }, this.props.id); 
      setTimeout(() => { 
       this.setState({ exitsStore: response }); 
      }, 200); 
      setTimeout(() => { 
       console.log(this.state.exitsStore); 
      }, 1000); 
     } 

Les journaux de la console sont vides pour la première fois « updateFirstInput() » est appelée et sont toujours un « onChange » derrière d'être précis.

qui est pour « bonjour »:

[input value] [ console log of value for which presence on the server is true/false] 
"h"    "" 
"he"    "h" 
"hel"   "he" 
"hell"   "hel" 
"hello"   "hell" 

après un certain temps, je compris que ce qui se passait.

J'ai essayé ceci:

const defaultProps = { 
    onChange:() => { 
    }, 
    value: { type: '' }, 
    provider: { type: '' }, 
}; 

class InputsComponent extends Component { 

    onChange =() => { 
     this.props.onChange(this.props.id); 
    }; 

checkExists(object){ 
    const { exists, response } = this.props; 
    const payload = { 
     objectType: this.props.placeholder.toLowerCase(), 
     objectName: object, 
    }; 
    exists(payload); 
    return response; 
} 

updateFirstInput(event) { 
    const { onChange } = this.props; 
    this.setState({ firstInput: event.target.value }); 
    onChange({ value: { 
     ...this.state, 
     firstInput: event.target.value, 
    } }, this.props.id); 
    const response = await this.checkExists(event); 

    console.log(response); 
    this.setState({ exitsStore: response }); 

    console.log('stored data :'); 
    console.log(this.state.exitsStore); 
} 

mais pour certaines personnes de raison qui suggère que nous utilisons en ligne await ne fournissent pas le contexte. ce qui précède n'est même pas compilable. (le démarrage de npm échouera)

et même avant que ESLint indique que "wait est un mot réservé attendant un saut de ligne ou un point-virgule". Mais je suis certain que ce qui précède, même avec une syntaxe correcte, ne fonctionnerait pas non plus.

il n'est probablement pas attendre mais comment puis-je avoir une réponse remplie du serveur (idéalement) au sein d'une seule fonction, la même fonction qui appelle la mise à jour d'entrée.

Constrainst:

pour autant que je sais que vous ne pouvez pas avoir les deux onBlur et onChange sur la même entrée afin que je suis déjà à l'aide onChange pas onBlur. Je ne peux pas appeler tout cela dans un parent ou autre: il y a plusieurs champs de saisie comme enfants et je dois avoir la valeur cocher et cocher les actions apparaissent dans l'enfant pour pouvoir faire correspondre les valeurs ensemble .

MISE À JOUR:

et si je retire simplement les minuteries:

const defaultProps = { 
    onChange:() => { 
    }, 
    value: { type: '' }, 
    provider: { type: '' }, 
}; 

class InputsComponent extends Component { 

    onChange =() => { 
     this.props.onChange(this.props.id); 
    }; 

updateFirstInput(event) { 
     const { onChange, exists, response } = this.props; 
     const payload = { 
      objectType: this.props.placeholder.toLowerCase(), 
      objectName: event.target.value, 
     }; 
     exists(payload); 
     this.setState({ firstInput: event.target.value }); 
     onChange({ value: { 
      ...this.state, 
      firstInput: event.target.value, 
     } }, this.props.id); 
     this.setState({ exitsStore: response }); 
     console.log(this.state.exitsStore); 
    } 

... deux appels derrière.

+0

Pour utiliser 'await', la fonction doit être' async'. vous pouvez utiliser les deux événements 'onChange' et' onBlur'. Pouvez-vous ajouter le code pour 'this.props.onChange' s'il vous plaît? – bennygenel

+0

fait. ça fait partie de la même classe. et merci pour l'info ne savait pas onChange et onBlur pourrait être utilisé ensemble. – tatsu

+0

aussi que voulez-vous dire par fonction doit être asynchrone? Ma fonction est décidément asynchrone comme tout dans JS. les choses s'exécutent dans un ordre complètement aléatoire (ce qui est ennuyeux IMO) Ive pas trouvé de solution pour combattre cet autre puis ajouter des timers – tatsu

Répondre

0

Les méthodes préexistantes pratiques de Réagir à la rescousse.

Dans ce cas: componentWillRecieveProps().

componentWillReceiveProps(newProps) { 
    const response = newProps.response; 
    const old = this.props.response; 
    console.log(response); 
    const id = this.props.id; 
    if (response !== old && response.objectIdentifier === id) { 
     if (response.activ) { 
      if (response.isthere) { 
       this.setState({ inputIcon: 4 }); 
      } else { 
       this.setState({ inputIcon: 3 }); 
      } 
     } else { 
      this.setState({ inputIcon: 2 }); 
     } 
    } 
} 
onChange =() => { 
    this.props.onChange(this.props.id); 
}; 
updateInput(event) { 
    const { onChange, exists, response } = this.props; 
    const inputValue = event.target.value; 
    this.setState({ input: inputValue }); 
    onChange({ value: { 
     ...this.state, 
     input: inputValue, 
    } }, this.props.id); 
    if (inputValue === '') { 
     this.setState({ inputIcon: 0 }); 
    } else { 
     const placeHolder = this.props.placeholder.toLowerCase(); 
     const objectIdentifier = this.props.id; 
     const payload = { 
      objectType: placeHolder, 
      objectName: inputValue, 
      objectIdentifier, 
     }; 
     exists(payload); 
     this.setState({ 
      existStore: response, 
     }; 
    } 
} 

la raison pour laquelle cela fonctionne est que componentWillRecieveProps() par défaut reçoit un paramètre qui est l'état des accessoires mis à jour et celui-ci est en effet le nouveau. vous pouvez vérifier qu'il y a bien eu une mise à jour en faisant ce que j'ai fait: vérifier l'objet que vous avez dans les accessoires par rapport au paramètre passé et n'effectuer vos actions que s'ils sont différents.

J'ai besoin de modifications sur ce poste s'il vous plaît, parce que je suis terrible à l'exprimer avec les termes de développement correct!

1

setState est asynchrone.Il semble que vous utilisiez des délais d'attente pour essayer de contourner ce problème, mais c'est une manière très brute et brutale de "résoudre" le problème et cela ne résout pas réellement le problème (comme le montrent vos résultats).

Mais setState a des gestionnaires disponibles lorsque vous devez exécuter du code "après". Vous le faites simplement en passant une fonction de rappel comme deuxième argument. Par exemple.;

this.setState({ 
    exitsStore: response 
},() => { 
    console.log(this.state.exitsStore); 
}); 
+0

Bien! C'est toujours un appel derrière. Je pense que c'est parce que, pour une raison quelconque, la première valeur tirée du réducteur est vide quand on la tire de cette façon. – tatsu