Comment créer des appels d'API dans REACT et FLUX
Je suis nouveau de réagir et de flux et je vais avoir un moment difficile essayer de trouver comment charger des données à partir d'un serveur. Je suis en mesure de charger les mêmes données à partir d'un fichier local avec pas de problèmes.
Donc tout d'abord j'ai cette vue contrôleur (controller-view.js) qui passe de l'état initial à une vue (view.js)
controller-view.js
var viewBill = React.createClass({
getInitialState: function(){
return {
bill: BillStore.getAllBill()
};
},
render: function(){
return (
<div>
<SubscriptionDetails subscription={this.state.bill.statement} />
</div>
);
}
});
module.exports = viewBill;
view.js
var subscriptionsList = React.createClass({
propTypes: {
subscription: React.PropTypes.array.isRequired
},
render: function(){
return (
<div >
<h1>Statement</h1>
From: {this.props.subscription.period.from} - To {this.props.subscription.period.to} <br />
Due: {this.props.subscription.due}<br />
Issued:{this.props.subscription.generated}
</div>
);
}
});
module.exports = subscriptionsList;
J'ai un fichier de scripts de chargement de la INITAL données de mon application. Donc, ce sont des données qui est pas appelé par l'action de l'utilisateur, mais appelée à partir de getInitialState dans le contrôleur de vue
InitialActions.js
var InitialiseActions = {
initApp: function(){
Dispatcher.dispatch({
actionType: ActionTypes.INITIALISE,
initialData: {
bill: BillApi.getBillLocal() //I switch to getBillServer for date from server
}
});
}
};
module.exports = InitialiseActions;
Et puis mes données API ressemble à ceci
api.js
var BillApi = {
getBillLocal: function() {
return billed;
},
getBillServer: function() {
return $.getJSON('https://theurl.com/stuff.json').then(function(data) {
return data;
});
}
};
module.exports = BillApi;
Et c'est le magasin
store.js
var _bill = [];
var BillStore = assign({}, EventEmitter.prototype, {
addChangeListener: function(callback) {
this.on(CHANGE_EVENT, callback);
},
removeChangeListener: function(callback) {
this.removeListener(CHANGE_EVENT, callback);
},
emitChange: function() {
this.emit(CHANGE_EVENT);
},
getAllBill: function() {
return _bill;
}
});
Dispatcher.register(function(action){
switch(action.actionType){
case ActionTypes.INITIALISE:
_bill = action.initialData.bill;
BillStore.emitChange();
break;
default:
//do nothing
}
});
module.exports = BillStore;
Donc, comme je l'ai mentionné plus tôt, lorsque je charge les données en local à l'aide de BillApi.getBillLocal() dans des actions tout fonctionne bien. Mais lorsque je change de BillApi.getBillServer (), je reçois le followind des erreurs dans la console...
Warning: Failed propType: Required prop `subscription` was not specified in `subscriptionsList`. Check the render method of `viewBill`.
Uncaught TypeError: Cannot read property 'period' of undefined
J'ai également ajouté une console.journal(données) pour les BillApi.getBillServer() et je peux voir que les données renvoyées par le serveur. Mais il est affiché APRÈS - je obtenir les mises en garde dans la console, qui je crois peut-être la question. Quelqu'un peut-il donner quelques conseils ou m'aider à résoudre ce problème? Désolé pour ce long post.
Mise à JOUR
J'ai apporté quelques modifications à la api.js fichier (cliquez ici pour le changement et DOM erreurs plnkr.co/modifier/HoXszori3HUAwUOHzPLG ) comme il a été suggéré que le problème est dû à la façon dont je gère la promesse. Mais il semble toujours être le même problème comme vous pouvez le voir dans les DOM erreurs.
source d'informationauteur Jose the hose
Vous devez vous connecter pour publier un commentaire.
C'est un async question. À l'aide de
$.getJSON().then()
n'est pas assez. Depuis elle renvoie une promesse d'objet, vous avez à gérer la promesse à l'invocation en faisant quelque chose commeapi.getBill().then(function(data) { /*do stuff with data*/});
J'ai fait un CodePen exemple avec le code suivant:
Il ressemble à partir de votre code que le flux est quelque chose comme:
Dans un typique flux de l'installation, je vous conseille de structure un peu différente:
getJSON
et attend les résultats de serveurJe ne suis pas si à l'aise avec jquery, des promesses et de l'enchaînement, mais je pense que ce serait à peu près traduire dans les modifications suivantes dans votre code:
componentDidMount()
fonction qui ajoute un écouteur d'événement de flux enregistrer les modifications.setState()
fonction qui récupère le plus récent _bill à partir de la boutique.dispatcher.dispatch()
à partir de votre actions.js pour votre api.js (en remplacement dereturn data
);De cette façon, votre composant initialement devrait rendre certains "chargement" du message, et de mettre à jour dès que les données à partir du serveur.
Une autre méthode serait de vérifier si l'hélice de l'abonnement existe avant de jouer avec les données.
Essayez de modifier votre code ressemble un peu à ceci:
Dans la fonction rendu avant le retour, essayez d'ajouter la suivante:
si(ce.accessoires de jeu.abonnement != undefined){
//faire quelque chose ici
}
En raison des données modification de l'état de haut niveau composant, il permettra de prolonger le rendu une fois les données avec l'abonnement prop.
Si je comprends bien, vous pourriez essayer avec quelque chose comme ça
$.getJSON ne pas renvoyer la valeur de la requête http. Il met à la disposition de la fonction de rappel.
La logique derrière cela est expliqué en détail ici: Comment faire pour retourner la réponse d'un appel asynchrone?
Je vais séparer mes Actions, de Magasins et de points de Vue (réaction de composants).
Tout d'abord, j'aimerais mettre en œuvre mon Action comme ceci:
La prochaine est mon Magasin, afin que je puisse garder une trace de tous les changements qui soudain peut se produire lors de mon appel d'api:
Enfin, votre composant:
En supposant que vous êtes réellement obtenir les données à partir de votre API, mais il y a trop tard et que les erreurs sont jetés tout d'abord, essayez ceci:
Dans votre controller-view.js ajouter le:
Et dans votre getInitialState fonction, donner un objet vide avec la structure de votre code prévoit (en particulier, ont une "déclaration" de l'objet à l'intérieur). Quelque chose comme ceci:
Ce qui se passe est que lorsque vous êtes l'obtention de votre état initial, il n'est pas l'extraction de les ranger correctement, et il en sera de retour un objet non défini. Lorsque vous demandez ensuite pour ce.état.le projet de loi.déclaration, le projet de loi est initialisé mais non définie, et donc il ne peut pas trouver quelque chose appelé déclaration, c'est pourquoi vous devez l'ajouter. Une fois que le composant a eu un peu plus de temps (c'est un async problème comme les autres affiches de le dire), il doit extraire correctement à partir du magasin. C'est pourquoi nous nous attendre pour la banque d'émettre le changement pour nous, puis on récupère les données à partir de la boutique.