Utilisez Async / wait avec Axios dans React.js
j'essaie de faire une requête get simple à mon serveur en utilisant Async/wait dans une React.js App.
Le serveur charge un JSON simple à /data
qui ressemble à ceci
JSON
{
id: 1,
name: "Aditya"
}
je suis capable d'obtenir les données de mon application React en utilisant la méthode simple jQuery ajax get. Cependant, je veux faire usage de la bibliothèque axios et Async / en attente de suivre les normes ES7. Mon code ressemble à ceci:
class App extends React.Component{
async getData(){
const res = await axios('/data');
console.log(res.json());
}
render(){
return(
<div>
{this.getData()}
</div>
);
}
}
en Utilisant cette approche, j'ai le erreur:
les Objets ne sont pas valides comme Réagir enfant (trouvé: [objet de la Promesse]). Si que vous vouliez rendre une collection d'enfants, utiliser un tableau à la place.
est-ce que je ne l'implémente pas correctement?
2 réponses
Deux questions sauter:
getData
ne retourne jamais rien, donc sa promesse (async
renvoient toujours une promesse de résoudre avecundefined
quand il se résoutle message d'erreur indique clairement que vous essayez de rendre directement la promesse
getData
retourne, plutôt que d'attendre qu'il se résolve et de rendre ensuite la résolution
Adressage #1: getData
devrait retour le résultat de l'appel à json
:
async getData(){
const res = await axios('/data');
return await res.json();
}
Addressig #2: nous aurions à voir plus de votre code, mais fondamentalement, vous ne pouvez pas faire
<SomeElement>{getData()}</SomeElement>
...parce que ça n'attend pas la résolution. Vous auriez besoin au lieu d'utiliser getData
pour définir l'état:
this.getData().then(data => this.setState({data}))
.catch(err => { /*...handle the error...*/});
...et l'utilisation que l'état lors du rendu:
<SomeElement>{this.state.data}</SomeElement>
mise à Jour: Maintenant que vous avez montré votre code, vous devez faire quelque chose comme ceci:
class App extends React.Component{
async getData() {
const res = await axios('/data');
return await res.json(); // (Or whatever)
}
constructor(...args) {
super(...args);
this.state = {data: null};
}
componentDidMount() {
if (!this.state.data) {
this.getData().then(data => this.setState({data}))
.catch(err => { /*...handle the error...*/});
}
}
render() {
return (
<div>
{this.state.data ? <em>Loading...</em> : this.state.data}
</div>
);
}
}
Plus de mise à jour: vous avez indiqué une préférence pour await
componentDidMount
plutôt que then
et catch
. Vous feriez cela en nichant un async
la vie fonctionne à l'intérieur de celui-ci et de s'assurer que cette fonction ne peut pas jeter. (componentDidMount
lui-même ne peut pas être async
, rien ne consume cette promesse.) E. g.:
class App extends React.Component{
async getData() {
const res = await axios('/data');
return await res.json(); // (Or whatever)
}
constructor(...args) {
super(...args);
this.state = {data: null};
}
componentDidMount() {
if (!this.state.data) {
(async () => {
try {
this.setState({data: await this.getData()});
} catch (e) {
//...handle the error...
}
})();
}
}
render() {
return (
<div>
{this.state.data ? <em>Loading...</em> : this.state.data}
</div>
);
}
}
Dans mon expérience au cours des derniers mois, j'ai réalisé que la meilleure façon d'y parvenir est:
class App extends React.Component{
constructor(){
super();
this.state = {
serverResponse: ''
}
}
componentDidMount(){
this.getData();
}
async getData(){
const res = await axios.get('url-to-get-the-data');
const { data } = await res;
this.setState({serverResponse: data})
}
render(){
return(
<div>
{this.state.serverResponse}
</div>
);
}
}
si vous essayez de faire une requête post sur des événements tels que click, alors appelez getData()
fonction de l'événement et de remplacer le contenu de celui-ci comme suit:
async getData(username, password){
const res = await axios.post('url-to-post-the-data', {
username,
password
});
...
}
de plus, si vous faites une demande lorsque le composant est sur le point de se charger, remplacez simplement async getData()
async componentDidMount()
et modifier le rendu de la fonction comme ceci:
render(){
return (
<div>{this.state.serverResponse}</div>
)
}