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:
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" }); }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.
