2017-11-02 1 views
0

Ich versuche, meine Komponente zu aktualisieren, auf ein Element zu löschen, habe ich den folgenden Code geschrieben:Update-Komponente auf Zustandsaktualisierungs Reagieren js

Profile.js:

class Profile extends Component { 
    constructor(props){ 
     super(props); 
     this.id = jwt_decode(sessionStorage.getItem('id_token'))['id']; 
     this.getUserData = this.getUserData.bind(this); 
     this.getUserAddresses = this.getUserAddresses.bind(this); 
     this.createUserAddressCards = this.createUserAddressCards.bind(this); 
     this.deleteUserAddress = this.deleteUserAddress.bind(this); 
     this.state = {} 
     this.user = new User(); 
    } 

    componentWillMount(){ 
     this.getUserData(this.id); 
     this.getUserAddresses(this.id); 
    } 

    getUserData(_id){ 
     var userPromise = this.user.user_data(_id); 
     userPromise.then(
      (val) => { 
       this.setState({email: val.email, 
           firstName: val.firstName, 
           lastName: val.lastName}); 
      } 
     )   
    } 

    getUserAddresses(_id){ 
     var addresses_promise = this.user.get_addresses(_id); 
     addresses_promise.then(
      (val) => { 
       this.setState({addresses: val}, function(){ 
        this.createUserAddressCards(this.state.addresses); 
       }); 
      } 
     ) 
    } 
    createUserAddressCards(_addresses){ 
     var addresCards = []; 
     for (var i=0; i < _addresses.length; i++) { 
      addresCards.push(
       <UserAddressCard 
        street={_addresses[i]['street']} 
        streetNumber={_addresses[i]['streetNumber']} 
        city={_addresses[i]['city']} 
        zipcode={_addresses[i]['zipCode']} 
        id={_addresses[i]['id']} 
        delete={this.deleteUserAddress} 
       />); 
     } 
     this.setState({cards: addresCards}); 
    } 
    deleteUserAddress(_address_id){ 
     this.user.delete_address_by_id(this.id, _address_id); 
     this.getUserAddresses(this.id); 
    } 

    render(){ 
     return(
      <div>    
       <Container className='content-container'> 
        <Row> 
         <Col md={4}> 
          <Card> 
           <CardBody> 
            <Row> 
             <Col md={12}> 
              <Button className='float-right' color='secondary' size='sm'> 
               <i className='fa fa-pencil'></i> 
              </Button> 
             </Col> 
             <Col className="card-row" md={12}> 
              <img className='profileImage' alt='Profile' src={logo} width={150} height={150}/> 
              <Table> 
               <tbody> 
                <tr> 
                 <th>Name</th> 
                 <td>{this.state.firstName}</td> 
                </tr> 
                <tr> 
                 <th>Surname</th> 
                 <td>{this.state.lastName}</td> 
                </tr> 
                <tr> 
                 <th>Email</th> 
                 <td>{this.state.email}</td> 
                </tr> 
                <tr> 
                 <th>Password</th> 
                 <td>********</td> 
                </tr> 
               </tbody> 
              </Table> 
             </Col> 
            </Row> 
           </CardBody> 
          </Card> 
         </Col> 
         <Col md={8}> 
          <Card> 
           <CardBody> 
            <Row> 
             <Col md={12}> 

              <Link exact to='profile/add/address' params={this.id}> 
              <Button className='float-right' size='sm' color='success'> 
               <i className="fa fa-plus"> 
               </i> 
              </Button> 
              </Link> 
             </Col> 
             <Col className='card-row' md={12}> 
              <Row> 
              {this.state.cards} 
              </Row> 
             </Col> 
            </Row> 
           </CardBody> 
          </Card> 
         </Col> 
        </Row> 
       </Container> 
      </div> 
     ) 
    } 
} 
export default Profile; 

UserAddressCard.js:

class UserAddressCard extends Component { 
    render(){ 
     return(
      <Col md={6}> 
       <Card> 
        <CardBody> 
         <CardText> 
          <Row> 
           <Col md={12} > 
            <div className="address-card"> 
            <b>Street: </b>{this.props.street} {this.props.streetNumber} 
            <ButtonGroup className="float-right"> 
             <Link to={'/profile/edit/address/' + this.props.id}>           <Button addressId={this.props.id} size='sm' color='warning'> 
               <i className="fa fa-pencil"/> 
              </Button> 
             </Link> 

             <Button onClick={()=>this.props.delete(this.props.id)} size='sm' color='danger'> 
              <i className="fa fa-minus"/> 
             </Button> 

            </ButtonGroup> 
            <br/> 
            <b>Zipcode: </b>{this.props.zipcode} 
            <br/> 
            <b>City: </b>{this.props.city} 
            </div> 
           </Col> 
          </Row> 
         </CardText> 
        </CardBody> 
       </Card> 
      </Col> 
     ) 
    } 
} 
export default UserAddressCard; 

user.js:

class User extends API{ 
    user_data(_id){ 
     return this.get('/account/users/' + _id); 
    } 
    add_address(_street, _streetNumber, _city, _zipcode, _id){ 
     return this.post('/account/users/' + _id + '/addresses', 
         {"street": _street, "streetNumber": _streetNumber, "city": _city, "zipCode": _zipcode}); 
    } 
    get_addresses(_id){ 
     return this.get('/account/users/' + _id + '/addresses'); 
    } 
    get_address_by_id(_user_id, _address_id){ 
     console.log('/account/users/'+ _user_id + '/addresses/' + _address_id); 
     return this.get(('/account/users/'+ _user_id + '/addresses/' + _address_id)); 
    } 
    delete_address_by_id(_user_id, _address_id){ 
     this.delete(('/account/users/'+ _user_id + '/addresses/' + _address_id)); 
    } 
} 
export {User}; 

api.js:

class API { 
    constructor() { 
     this.API_url = 'http://localhost:5000/api' 

    } 



    /** 
    * Sends POST request to API. 
    * 
    * var _endpoint - (String) API endpoint (part after the base URL). 
    * var _data  - (Array) array that will be send to the server. 
    * 
    * returns promise 
    */ 

    async post(_endpoint, _data) { 
     console.log(JSON.stringify(_data)); 
     console.log(_endpoint); 
     let response = await fetch(this.API_url + _endpoint, { 
      method: "POST", 
      headers: { 
       'Content-Type': 'application/json', 
      }, 
      body: JSON.stringify(_data) 
     }) 

     return response.json(); 
    } 

    /** 
    * Sends GET request to API. 
    * 
    * var _endpoint - (String) API endpoint (part after the base URL). 
    * 
    * returns promise 
    */ 

    async get(_endpoint) { 
     let response = await fetch(this.API_url + _endpoint); 
     return response.json(); 
    } 

    async delete(_endpoint){ 
     let response = await fetch(this.API_url + _endpoint, { 
      method: "DELETE" 
     }); 
    } 
} 

// Export API for global use 
export { API } 

ein Element Löschen funktioniert, aber wenn ich auf die Schaltfläche wird die Seite nicht erneut gerendert. Ich verstehe nicht warum, denn beim Löschen rufe ich eine Methode auf, die den Status mit neuen UserAddressCards aktualisiert.

Kann mir jemand helfen?

+0

Können Sie den Code hinzufügen, wo Sie 'UserAddressCard' anrufen? – yuantonito

+0

Es ist die Funktion CreateUserAddressCards, diese speichert die Karten in einer Var "cards" in dem Zustand. Dann rufe ich die this.state.cards im Render @yuantonito –

+0

Ist 'this.user.delete_address_by_id' async? Sie rufen 'this.getUserAddresses' in der nächsten Zeile auf und ich nehme an, es ist bevor die Adresse gelöscht wurde. Aber ohne Zugriff auf den relevanten Teil von "User" ist es nur eine Vermutung. – pawel

Antwort

0

Ihre Artikel korrekt gelöscht werden, aber die Seite nicht erneut gerendert, weil Sie die userAddressesvor holen beendet hat Löschen der userAddress

Sie folgendes tun sollten:

deleteUserAddress(_address_id){ 
    this.user.delete_address_by_id(this.id, _address_id) 
    .then(id => this.getUserAddresses(this.id)); 
} 

Oder wenn Sie async/await in Ihrem Projekt

async deleteUserAddress(_address_id) { 
    const result = await this.user.delete_address_by_id(this.id, _address_id); 
    this.getUserAddresses(this.id); 
} 

Hinweis: Es ist keine bewährte Methode, Komponenten direkt in diesem Zustand zu handhaben. Im Grunde Ihre Operation zu UserAddressCard in this.state.cards hinzufügen, sollten Sie stattdessen diesen Code in den Render schreiben und nicht im Zustand speichern.

+0

Wenn ich die erste Option verwende, sagt React, dass this.user.delete_address_by_id nicht definiert ist. Zweite Option funktioniert nicht. –

+0

Meine schlechte zweite Option funktioniert! Vielen Dank! –