Lorsque je supprime un circuit (via le lien sur la page de détails) et que je redirige vers la page d'accueil, l'objet que j'ai supprimé est toujours là jusqu'à ce que j'actualise manuellement la page.
J'ai essayé de passer des accessoires via le routeur:
handleDeleteCircuit = (event) => {
const circuitID = this.props.match.params.id;
axios.delete(`link-to-api`, this.state);
this.props.history.push('/');
this.forceUpdate();
}
J'ai essayé de déplacer la fonction de suppression du conteneur de vue de détail vers le conteneur de vue de liste, mais je n'arrive pas à comprendre comment transmettre la fonction à travers les composants.
L'action de suppression
<Route exact path='/' render={(props) => <CircuitList {...props} /> } />
Chaque fois que je supprime un circuit, il supprime de l'API, mais lorsqu'il redirige vers la page d'accueil , il est toujours là jusqu'à ce que j'actualise manuellement la page.
4 Réponses :
Vous n'avez aucun code qui supprime le circuit de la liste des circuits.
Quelque chose comme ça:
let this.state.circuits = this.state.circuits.filter((circuit) => {
return circuit.id == circuitId
})
Je ne suis pas familier avec React alors peut-être cela nécessite quelques modifications.
Vous devez supprimer des éléments de l'état (si celui-ci est à l'état de réaction, alors supprimer de l'état de réaction. S'il est en redux, supprimer l'élément de l'état de redux)
Ou vous pouvez à nouveau récupérer tous les éléments du backend pendant que votre route index est de nouveau montée (dans componentDidMount ), mais comme les appels réseau sont plus lourds que la manipulation d'état. J'opterais pour une approche optimiste de la suppression des éléments de l'état (que ce soit react ou redux ou toute autre bibliothèque de gestion d'état que vous utilisez)
handleDeleteCircuit = async (event) => {
const circuitID = this.props.match.params.id;
await axios.delete(`link-to-api`, this.state);
const circuits = [...this.state.circuits];
const index = array.indexOf(circuitID)
//or remove element from the redux state
if (index !== -1) {
circuits.splice(index, 1);
this.setState({circuits});
}
this.props.history.push('/');
this.forceUpdate();
}
Juste pour que je comprenne, si j'utilise le premier exemple, cela est censé manipuler l'état sur la page d'accueil afin que les consts et les noms soient les mêmes?
Evidemment non, mais vous devez alors envoyer un rappel à ce composant. Pour que vous puissiez dire à la page d'accueil quel circuitID a été supprimé
Le tableau dans array.indexOf est-il censé référencer les nouveaux circuits de tableau dans votre code? Aussi - cela supprime l'objet mais ne redirige pas uniquement si je supprime this.forceUpdate (); mais quand j'inclus forceUpdate, il ne supprime pas.
Vous n'avez pas à faire forceUpdate si vous modifiez l'itinéraire. array.indexOf trouve l'index de circuitId que vous souhaitez supprimer dans le tableau
Si vous utilisez un magasin redux pour gérer les éléments de la CircuitList , une cause possible est que même si l'entrée est supprimée via un appel api, les données persistent dans le magasin redux, ce qui devra également être actualisé une fois l'entrée supprimée.
Ce que vous voyez dans le rendu est ce que vous avez dans votre état.
TL; DR Vous devez mettre à jour votre état.
Vous avez donc deux possibilités.
Mise à jour optimiste, lancez l'api de suppression sur le serveur + setState pour supprimer les données dans votre état. Et après avoir reçu la réponse de l'API de suppression, agissez en conséquence.
Après le feu, supprimez l'API, récupérez à nouveau toutes les données du serveur et mettez à jour l'état.
Je suggérerais l'option 1 car elle semble plus rapide pour l'utilisateur.
Voici un concept supplémentaire.
Si vous souhaitez partager l'état (données) avec votre page "CircuitList" et "CircuitDetail". Vous devez stocker les circuits dans certains parents, comme App (ou état Redux), puis les transmettre à chaque composant.
Encore une fois, le modèle de mise à jour optimiste. Fire API + setState immédiatement ... revenir en arrière si les choses tournent mal.
Faites-moi savoir si vous avez besoin d'aide supplémentaire :)
Voici ce que vous pouvez faire.
// assuming you have your data in App, state.circuits
class App extends React.Component {
state = {
circuits: [
{ id: 1, title: 'Circuit 1' },
{ id: 2, title: 'Circuit 2' },
{ id: 3, title: 'Circuit 3' },
],
}
afterDeleteCircuit = (circuitID) => {
// state, before delete anything
const currentCircuits = this.state.circuits;
// Remove deleted item from state.
this.setState({
circuits: currentCircuits.filter(circuit => circuit.id !== circuitID),
});
// Fire delete API
axios
.delete(`link-to-api`, this.state)
.then(response => {
if (response.status === 'error') {
// Oops, something went wrong. Let's get that deleted Id back.
this.setState({
circuits: currentCircuits,
});
// Show Error message here.
} else {
// Delete successfully, do nothing.
// Because we already remove the deleted id from state.
// Show success message here.
}
});
}
render() {
return (
<Router>
<Route exact path='/' render={(props) => <CircuitList {...props} circuits={this.state.circuits} /> } />
<Route path='/circuits/:id' render={(props) => <CircuitDetail {...props} onDelete={this.afterDeleteCircuit} /> } />
</Router>
);
}
}
class CircuitList extends React.Component {
render () {
const { circuits } = this.props;
return (
<div>
{circuits.map(circuit => (
<li>{circuit.title} <Link to={`/circuit/${circuit.id}`}>Edit</Link></li>
)}
</div>
);
}
}
class CircuitDetail extends React.Component {
handleDelete = (e) => {
const { match, history } = this.props;
const id = match.params.id;
this.props.onDelete(id);
history.push('/');
}
render () {
return (
<div>
...
// Delete button
<button onClick={this.handleDelete}>Delete</button>
</div>
);
}
}
p>
Est-ce que quelque chose changerait si mes données étaient dans CircuitList par rapport à App?
CircuitDetail est-il dans App ou CircuitList?
Quoi qu'il en soit, vous pouvez utiliser ce principe lors de la conception où conserver l'état / les données ... "les données passent toujours, les événements passent toujours". C'est donc un anti-pattern de transmettre les données (CircuitList => App) avant de les transmettre à CircuitDetail. C'est pourquoi stocker des données dans
Merci pour le conseil! J'ai réorganisé mon application et elle est supprimée, mais elle ne redirige pas vers la page d'accueil. Dois-je ajouter `this.history.push ('/')?
Pour une raison quelconque, lorsque j'ajoute this.props.history.push ('/'); il ne supprime plus et il ne redirige pas.
'afterDeleteCircuit' est-il appelé? console.log devrait clarifier le problème
L'objet est supprimé avec succès, mais j'obtiens une erreur 404 avec Cannot GET from api et une erreur Uncaught (in promise): . Comment peut-il supprimer mais ne pas être appelé?
Essayez de remplacer axios.delete ( link-to-api ) par le chemin réel vers l'api.
J'ai fait. Je n'ai mis un lien vers l'API dans la question que parce que ce n'était pas important pour la question.
Récupérez-vous les éléments sur
componentDidMountdans HomePage?Non, je les supprime sur une page vue détaillée et je redirige vers la page d'accueil.
Vous devez montrer comment vous récupérez et définissez les données en premier lieu.