javascript - React-komponentin uudelleenrenderöinti AJAX-pyynnön jälkeen


Rakennan CRUD-sovellusta Reactilla ja mietin, voisitko auttaa tässä asiassa.

Teen AJAX GET -pyynnön palvelimelle componentDidMount-metodilla, joka hakee tiedot ja asettaa sitten tilan onnistumistoiminnossa. Renderöintifunktiossa käyn sitten state-taulukon läpi ja renderöin jokaisen tilan <li>-elementtiin ja lisään <button>-elementin.

Kun <button>-elementtiä klikataan, se kutsuu delete()-funktiota. Tämä kutsuu sitten AJAX DELETE -pyynnön ID:lle.

Ongelmani on, miten saan komponentin uudelleen renderöitymään tai päivittämään tilan sen jälkeen, kun AJAX-pyyntö onnistuu?

import React from 'react';

class PostList extends React.Component {
  constructor() {
    super();
    this.state = {
      posts: []
    }
  }

  componentDidMount() {
    $.ajax({
       url: '/posts',
       type: "GET",
       dataType: 'json',
       cache: false,
       success: function(data) {
         this.setState({posts: data})
       }.bind(this)
    });
  }

  delete(event) {
    let postId = event.target.parentNode.getAttribute("data-id");
      $.ajax({
         url: '/posts/' + postId,
         type: "DELETE",
         success: function(data) {
          console.log(data);
         }.bind(this)
      });
  }

  render() {
    let posts = this.state.posts.map( (index) => {
      return <li data-id={index._id} className="list-group-item"><a href={"posts/" + index._id}>{index.title}</a><button className="btn btn-default" onClick={this.delete.bind(this)}>Delete</button></li>
    })
    return (
      <ul className="list-group">
        {posts}
      </ul>
    )
  }
}

export default PostList;

Vastaus #1

Päivitä tila delete-käsittelijässä.

Sinulla on kaksi vaihtoehtoa:

  1. optimistinen, se päivittää käyttöliittymän välittömästi, mutta pyyntö voi epäonnistua ja sinun täytyy käsitellä tämä tapaus.

    delete(event) {
      let postId = event.target.parentNode.getAttribute("data-id");
      this.setState({
        posts: this.state.posts.filter(post => post._id !== postId)
      })
      $.ajax({
         url: '/posts/' + postId,
         type: "DELETE"
      });
    }
    
  2. pessimistinen, muuttaa tilaa vain onnistuneen pyynnön yhteydessä, mutta voi kestää hetken ennen kuin käyttöliittymä päivittyy.

    delete(postId) {
      $.ajax({
         url: '/posts/' + postId,
         type: "DELETE",
         success: function(data) {
          this.setState({
            posts: this.state.posts.filter(post => post._id !== postId)
          })
         }.bind(this)
      });
    }
    

Tilanhallinnan käsittelemiseksi voisit tutustua tilanhallintakirjastoihin kuten Redux.

Vastaus #2

Voit pakottaa päivityksen käyttämällä komponentin forceUpdate()-metodia. Se varmistaa, että komponentti renderöidään uudelleen. Olisi kuitenkin parempi, jos vastaisit siihen, mitä kyseinen kutsu palautti asettamalla tilan, mikä myös renderöi uudelleen.