2017-12-13 2 views
1

Arbeitet derzeit an einer App, die Axios-Anforderungen vom Client-Server an den Back-End-Server stellt.Wie mit asynchronen Funktionen arbeiten?

Manchmal wird die Anwendung korrekt aktualisiert und manchmal wird sie verzögert/wird erst bei der nächsten Anforderung aktualisiert. Irgendeine Idee warum?

Ist in meinem Code etwas nicht in Ordnung? Ich werde versuchen, alles hinzuzufügen, was relevant ist.

Die App ist eine Einkaufsliste, wo der Benutzer einfach über Google oauth anmelden kann. Sie fügen Elemente aus React State und einer MongoDB-Datenbank hinzu oder entfernen sie daraus.

Der Status der Liste wird jedes Mal aus der Datenbank abgerufen, wenn ein Element hinzugefügt/entfernt wird.

App Komponente

import React from 'react'; 
import ListForm from './ListForm'; 
import ListItem from './ListItem'; 
import * as helpers from '../helpers'; 

class App extends React.Component{ 
    state = { 
    currentUser: {}, 
    items: [] 
    } 

    componentDidMount() { 
    helpers.fetchUser() 
     .then(data => { 
     this.setState({ 
      currentUser: data, 
      items: data.shoppingList 
     },() => { 
      console.log(this.state) 
     }); 
     }); 
    } 

    // Handle adding new items 
onSubmit = (item) => { 
    this.setState({items: this.state.items.concat([item])}); 
    helpers.addItem(item) 
    .then(
     helpers.fetchUser() 
     .then(data => { 
      this.setState({ 
      currentUser: data, 
      items: data.shoppingList 
      },() => { 
      console.log(this.state); 
      }); 
     }) 
    ) 
    } 

    // Handle deletion of items 
    onDelete = (deleteItem) => { 
    helpers.removeItem(deleteItem) 
     .then(
     helpers.fetchUser() 
      .then(data => { 
      this.setState({ 
       currentUser: data, 
       items: data.shoppingList 
      },() => { 
       console.log(this.state); 
      }) 
      }) 
    ) 
    } 

    renderContent =() => { 
    const shoppingList = this.state.currentUser.shoppingList; 
    const currentUser = this.state.currentUser; 

    if(!currentUser.googleId) { 
     return (
     <div className="row justify-content-center"> 
      <div> 
      <a href="/auth/google" className="btn btn-primary"><i className="fa fa-google" /> Sign in with Google</a> 
      </div> 
     </div> 
     ); 
    } else if(shoppingList === undefined || shoppingList.length < 1) { 
     return (
      <div className="row justify-content-center"> 
      <h5>Add your first item!</h5> 
      </div> 
     ); 
    } else { 
     return (
      <div> 
      {this.state.items.map((item, index) => 
       <ListItem 
       {...item} 
       key={index} 
       id={index} 
       currentUser={this.state.currentUser} 
       onDelete={this.onDelete} 
       /> 
      )} 
      </div> 
     ); 
    } 
    } 

    render() { 
    return (
     <div className="container row offset-4"> 
     <div className="jumbotron col-sm-6"> 
      <ListForm 
      currentUser={this.state.currentUser} 
      items={this.state.items} 
      onSubmit={this.onSubmit} 
      /> 
      {this.renderContent()} 
     </div> 
     </div> 
    ); 
    } 
}; 

export default App; 

Liste Komponente

import React from 'react'; 

class ListForm extends React.Component { 
    state = { 
    value: '' 
    } 

    // Handle the submission of a new item to database and state. 
    handleSubmit = e => { 
    e.preventDefault(); 

    this.props.onSubmit({name: this.state.value}); 
    this.setState(prevState => ({value: ''})); 
    } 

    // Handle any changes within the input. 
    onChange = e => { 
    this.setState({value: e.target.value}); 
    } 

    render() { 
    return (
     <div className="col-xs-9"> 
      <h3>Grocery List</h3> 
     <form className="form-control" onSubmit={this.handleSubmit}> 
      <input style={{display: "inline", width: "60%", height: "2em"}} className="form-control" type="text" 
      value={this.state.value} 
      onChange={this.onChange} 
      required 
      /> 
      <button className="btn btn-success btn-sm float-right">Add item</button> 
     </form> 
     <div style={{marginTop: "10%"}}> 
     </div> 
     </div> 
    ); 
    } 
} 

export default ListForm; 

Helpers.js (Wo Anträge sind)

import axios from 'axios'; 

export const fetchUser = async() => { 
    const resp = await axios.get('/api/current_user'); 

    return resp.data; 
} 

export const addItem = async (newItem) => { 
    const resp = await axios.post("/api/addItem", newItem); 

    return resp.data; 
} 

export const removeItem = async (deleteItem) => { 
    axios.delete("/api/removeItem", {data: {item: deleteItem}}); 
} 

Verbindungen zu und zwischen mir Benutzerdaten

const mongoose = require('mongoose'); 
const User = require('../models/userSchema'); 

module.exports = (app) => { 
    app.post('/api/addItem', async (req, res) => { 
    const item = await req.body; 

    req.user.shoppingList.push(item); 
    req.user.save(); 

    console.log(req.user); 

    res.send(item); 
    }); 

    app.delete('/api/removeItem', (req, res) => { 
    const itemName = req.body.item; 
    console.log(itemName); 
    const index = req.user.shoppingList.findIndex(i => i.name === itemName); 
    console.log(index); 

    req.user.shoppingList.splice(index, 1); 
    req.user.save(); 

    console.log(req.user); 

    res.send(itemName); 
    }); 
}; 

Bitte lassen Sie wissen, ob ich etwas hinzufügen, um brauchen, um dies deutlicher zu machen!

+0

Es wäre besser, wenn Sie Ihren Status mit [Redux] (https://redux.js.org/docs/basics/UsageWithReact.html) zentralisieren, so dass Sie es einfach verwalten –

+1

Danke, das Ziel war, nur React zu verwenden obwohl! –

Antwort

0

Es ist schwer zu sagen, wenn Sie den Code betrachten, denn es gibt keine .catch Klauseln nach Ihrem 's. Das wäre der erste Ort, um zu überprüfen: Was ist, wenn Ihre Anfrage manchmal fehlschlägt? Außerdem ist die Devotools-Erweiterung "React" ideal, um den Status zur Laufzeit zu überprüfen. Wenn es sich nicht um ein Versprechensproblem handelt, können Sie es mit Sicherheit festhalten.

+0

Danke dafür. Ich denke, dass das mit der Tatsache zusammenhängen könnte, dass ich im Wesentlichen zwei Anfragen beantworte. (helpers.addItem und dann helpers.fetchUser). Ich könnte einfach helpers.addItem ausführen und den Status in einem .then() mit den zurückgegebenen und aktualisierten Daten aktualisieren. –

+0

eine andere Sache! Ohne zu viel Kontext ist es schwer zu sagen, ob das ein echter Fehler ist. Wenn die Komponente geladen wird, rufen Sie Benutzerdaten ab und setzen sie auf Status. Beim Hinzufügen von Elementen rufen Sie die Benutzerdaten erneut ab. Ist das Abrufen von Benutzerdaten ein Fn, der eine Zusage zurückgibt, die nach Benutzerdaten sucht, und wenn dies der Fall ist, oder wird sie nur erneut abgefragt? wenn das letztere die Quelle sein könnte, sonst wahrscheinlich keine Sorgen – adamz4008

+0

helpers.fetchUser() ist nur eine Axios-Anfrage an den Server –

Verwandte Themen