Je suis nouveau dans les hooks de réaction et je ne vois tout simplement pas cela sur les documents:
const MyComponent = ({myProp}) => {
const [myPropHook, setPropHook] = useState(myProp)
...
}
Je me demande si c'est une bonne pratique?
p >
4 Réponses :
La valeur que vous transmettez à useState est utilisée comme valeur de départ pour la variable d'état. Ainsi, lorsque vos accessoires de composant changent, ils n'affecteront pas la variable d'état que vous utilisez. La valeur initiale serait les premiers accessoires envoyés au composant et après cela, ils ne peuvent être modifiés qu'à l'aide de la fonction setPropHook .
Donc, en bref, c'est définitivement une odeur de code d'utiliser des accessoires comme initialiseurs pour useState car la lecture du code ne transmet pas correctement ce qui va réellement se passer.
Vous ne le voyez pas beaucoup, car cela n'a pas beaucoup de sens en ce qui concerne la façon dont une application React devrait distribuer son état.
Si une valeur de prop est définie plus haut dans l'arborescence, elle ne doit pas être utilisée comme partie de l'état séparé au sein d'un composant. Il est logique d'utiliser des valeurs de prop pour déterminer l'état d'un composant indirectement comme dans «si le prop est ceci, alors définissez l'état sur cela», mais pas pour copier directement le prop dans l'initiale valeur.
En d'autres termes, l'état interne d'un composant (accessible via les hooks useState et useReducer ) doit être déterminé par le composant, pas directement par le (s) parent (s) ).
Oui, c'est mauvais. Ce que vous faites, c'est passer un accessoire à l'État, et cela est découragé par beaucoup.
La documentation React dit que "l'utilisation d'accessoires pour générer l'état conduit souvent à la duplication de la" source de vérité ", c'est-à-dire où se trouvent les données réelles." . Le danger est que si les props sont modifiés sans que le composant soit actualisé, la nouvelle valeur de prop ne sera jamais affichée, car l'initialisation de l'état à partir des props ne s'exécute que lors de la création du composant.
La seule exception serait d'utiliser le prop comme une graine pour un état contrôlé en interne. Après plusieurs années de développement de réaction, je n'ai jamais rencontré un tel cas.
Lectures complémentaires:
État d'initialisation du composant React à partir des accessoires (question SO)
React Anti-Patterns: Props in Initial State a> (article de medium.com)
Définition de la raison Props as State in React.js is Blasphemy (article de blog)
Si vous essayez de recevoir un accessoire pour ce composant fonctionnel, alors oui, mais pas exactement comme vous l'avez écrit. Donc, dans le composant parent, vous aurez quelque chose comme ceci:
const ResourceList = ({ resource }) => {
const [resources, setResources] = useState([]);
et puis il y a un composant à l'intérieur du JSX comme ceci:
const ResourceList = (props) => {
const [resources, setResources] = useState([]);
Ce composant ResourceList doit pouvoir recevoir les accessoires que le composant App lui transmet. Dans un composant basé sur une classe, vous feriez {this.props.resource} , mais dans notre cas, où c'est un composant fonctionnel utilisant des hooks React, vous voulez l'écrire comme ceci:
XXX
ou via une déstructuration ES6 comme ceci:
const App = () => {
const [resource, setResource] = useState("posts");
return (
<div>
<div>
<button onClick={() => setResource("posts")}>Posts</button>
<button onClick={() => setResource("todos")}>Todos</button>
</div>
<ResourceList resource={resource} />
</div>
);
};
À mon avis, cela convient si vous prévoyez d'utiliser
myPropuniquement comme valeur initiale, sinon je vous suggérerais d'utiliseruseRef ()au cas où vous auriez besoin de mettre à jour votre état local lorsquemyPropchange.Il existe un cas d'utilisation raisonnable pour cela. Si, par exemple, vous avez un formulaire et que les accessoires contiennent l'état du serveur d'un objet, vous voulez que l'état contienne ce que l'utilisateur a actuellement tapé et que les accessoires ne se mettent à jour qu'une fois que le serveur a mis à jour l'état de l'objet.
@apokryfos Dans cet exemple, vous devez utiliser les accessoires jusqu'à ce que l'état interne soit mis à jour.
@WillJenkins Pour clarifier. L'état interne est par ex. une ligne de base de données sur le serveur. Les accessoires contiennent les données de ligne. L'état du composant contiendra les modifications de l'utilisateur sur ces données, mais les accessoires ne doivent pas être mis à jour tant que les données modifiées ne sont pas transmises au serveur et que le serveur met à jour la ligne. Dans ce cas, ne pas utiliser l'état signifie que vos entrées de formulaire seront en lecture seule. cela suppose qu'il y aura un bouton d'envoi qui déclenche la mise à jour du serveur par opposition à une boîte de type mise à jour au fur et à mesure