Back home

SwiftUI Series 04|Gestion de l'état SwiftUI : sélection de @State, @Binding, @ObservedObject, @StateObject

La vraie clé est de répondre d’abord : « À qui appartiennent ces données et qui pilote les modifications de l’interface ? »

L’endroit où les gens sont le plus susceptibles de rester « bloqués » dans SwiftUI est l’État.

Les questions les plus courantes sont généralement les suivantes :

  • Devons-nous utiliser @State ou @Binding pour cette valeur ?
  • ViewModel sera initialisé à plusieurs reprises
  • Pourquoi la sous-vue ne peut-elle pas modifier les données de la vue parent ?
  • La valeur a évidemment changé, mais la page n’est pas rafraîchie comme prévu.

Si vous comptez uniquement sur la mémorisation des wrappers d’attributs pour ces problèmes, il est facile de devenir de plus en plus confus. Parce que la véritable cause profonde est généralement :

Sans réfléchir clairement au préalable à « à qui appartient cet État ?

1. Ne vous précipitez pas pour choisir un emballage. Demandez d’abord : à qui appartiennent ces données ?

C’est la question la plus importante.

Dans SwiftUI, chaque fois que vous voyez une valeur d’état, demandez-vous :

  • Cette valeur appartient-elle à la vue actuelle ?
  • La vue parent en est toujours propriétaire et la sous-vue est simplement empruntée et modifiée.
  • Toujours appartenant à un objet externe, la vue actuelle ne fait qu’observer

Une fois que cette question aura reçu une réponse claire, de nombreux choix d’emballages viendront naturellement. Au contraire, si vous sautez cette étape et demandez directement « lequel est couramment utilisé dans ce scénario », il sera facile d’empiler le code par essais et erreurs.

2. @State est vraiment adapté à “l’état local de la vue actuelle”

Le @State convient le mieux pour :

Cet état n’appartient qu’à la Vue actuelle. L’existence locale, la consommation locale et le fait de quitter ce point de vue n’ont fondamentalement aucun sens.

Par exemple :

  • Le contenu actuel de la zone de saisie
  • S’il faut afficher la feuille
  • Un certain état partiellement expansé et effondré
  • Sélection de l’onglet actuel

Ce que ces États ont en commun est :

  • Propriété claire
  • Le cycle de vie est fortement lié à cette vision
  • Ne vaut pas la peine de passer au statut d’entreprise externe

Si un élément d’état n’a pas de sens en dehors de la vue actuelle, il convient généralement bien à @State.

3. Le point clé de @Binding est que “la propriété n’a pas changé, mais l’autorisation d’écriture a été prêtée”

Une situation courante consiste à comprendre @Binding comme « les sous-vues peuvent également modifier la valeur de la vue parent ». Cette compréhension n’est pas fausse, mais elle n’est pas assez précise.

De plus :

  • Cet état appartient toujours à la vue parent
  • la sous-vue n’en est pas propriétaire
  • La sous-vue n’obtient que les canaux de lecture et d’écriture

Cette question est essentielle car elle détermine si l’attribution correcte des données est conservée lors de la notation du composant.

C’est à dire :

  • @State est “le mien”
  • @Binding est “toujours le même, mais je suis autorisé à le changer”

Une fois compris en termes de propriété, le @Binding ne peut plus être confondu avec une « solution universelle de partage de données ».

4. @ObservedObject et @StateObject se confondent plus facilement car les gens mélangent souvent « observation » et « possession »

L’utilisation abusive la plus courante de ces deux wrappers vient essentiellement du même problème :

Il n’est pas clair si « la vue actuelle observe un objet externe » ou « la vue actuelle crée et maintient cet objet de manière stable ».

@ObservedObject

Il vaut mieux exprimer :

  • Cet objet est transmis de l’extérieur
  • La vue actuelle l’observe simplement
  • La vue actuelle n’est pas responsable de sa création, ni de sa tenue stable.

@StateObject

Il vaut mieux exprimer :

  • La vue actuelle crée elle-même cet objet
  • et je souhaite le maintenir de manière stable pendant l’actualisation de la vue

La différence fondamentale entre les deux n’est pas « lequel est le plus avancé », mais plutôt :

  • qui a créé l’objet
  • Qui est responsable du cycle de vie des objets

Cela montre également que de nombreux problèmes d’initialisation répétée de ViewModel sont essentiellement dus à une propriété d’objet mal placée.

5. Un jugement d’ingénierie très pratique : le statut d’assurance-chômage local et le statut d’entreprise doivent être considérés séparément

Le statut de nombreuses pages sera source de confusion et le statut des différents niveaux sera regroupé en une boule.

Par exemple, une page peut contenir :

  • Contenu de la zone de saisie
  • Filtrer si la fenêtre pop-up est ouverte
  • Résultats de la demande de réseau
  • État de chargement de la page
  • Liste d’objets métier

Ces valeurs semblent être appelées « État », mais elles ne correspondent pas au même type d’État.

Je le divise généralement en deux catégories :

1. État de l’interface utilisateur locale

Par exemple :

  • S’il faut étendre
  • Contenu d’entrée actuel
  • Élément actuellement sélectionné
  • Commutateur d’affichage partiel

Ce type de statut est plus proche de @State / @Binding.

2. Statut des données professionnelles

Par exemple :

  • Informations utilisateur
  • Liste des données
  • Processus de chargement
  • Erreur de demande

Ce type d’état est généralement mieux placé dans un objet observable externe ou dans un conteneur d’état de niveau supérieur.

Une fois que ces deux types d’états ne sont pas distingués, la page aura facilement des valeurs de transmission d’état local, d’état ViewModel et de couche parent. En fin de compte, on ne sait pas à qui il appartient.

6. De nombreux problèmes de type « la valeur a changé mais l’interface est incorrecte » sont essentiellement causés par le mélange des frontières des États.

Une situation courante est la suivante :

  • J’ai évidemment changé la valeur, mais pourquoi la page n’a-t-elle pas changé comme je le pensais ?

Bien sûr, il s’agit parfois du mauvais emballage, mais le plus souvent :

  • L’état qui devrait appartenir à la couche parent est temporairement détenu par la couche enfant.
  • Les objets qui auraient dû exister depuis longtemps sont traités comme des objets d’observation temporaires.
  • Le statut de l’interface utilisateur locale et le statut de l’entreprise s’écrasent

En d’autres termes, ce qui ressemble à un « problème de rafraîchissement » est souvent en réalité un problème de propriété.

Pour de nombreux problèmes d’état dans SwiftUI, une fois que vous avez coché « à qui appartiennent ces données », vous pouvez généralement trouver la cause première plus rapidement que de regarder le phénomène d’interface.

7. Une méthode de jugement simplifiée que j’utilise souvent

Bien que les projets réels soient plus compliqués, j’utilise souvent cet ensemble de jugements simples dans le développement quotidien :

1. S’agit-il de l’état simple de la vue actuelle elle-même ?

Oui, donner la priorité à @State

2. Est-ce que cela appartient à la vue parent et est-il simplement emprunté et modifié par la sous-vue actuelle ?

Oui, donner la priorité à @Binding

3. S’agit-il d’un objet observable transmis de l’extérieur ?

Oui, donner la priorité à @ObservedObject

4. S’agit-il d’un objet que la vue actuelle a créé et qu’elle espère conserver de manière stable ?

Oui, donner la priorité à @StateObject

Cet ensemble de jugements ne couvre certes pas tous les détails, mais il est suffisamment pratique pour un grand nombre de pages commerciales.

8. Conclusion : Ce que nous devons d’abord comprendre à propos de la gestion de l’État, c’est la propriété.

Pour le dire sous une forme plus courte, je dirais :

Dans SwiftUI, la chose la plus importante à propos de la gestion de l’état est de demander d’abord “À qui appartiennent ces données et qui est responsable de la modification de l’interface avec celles-ci”.

Une fois que la propriété est claire, de nombreux choix d’emballage viendront naturellement. D’un autre côté, si vous ne réfléchissez pas clairement à la propriété et ne vous familiarisez pas avec l’API plus tard, il sera facile d’écrire une page qui « fonctionne mais devient de plus en plus compliquée ».

FAQ

What to read next

Related

Continue reading