J'essaye de convertir ce composant de classe en composant fonctionnel en utilisant des hooks
import React, { Component, cloneElement } from 'react'; class Dialog extends Component { constructor(props) { super(props); this.id = uuid(); } render(){ return ( <div>Hello Dialog</div> ); } }
Ce composant est lancé avec un ID spécifique car je devrai peut-être en utiliser plusieurs instances. Comment puis-je y parvenir si j'utilise un composant fonctionnel?
4 Réponses :
Une solution consisterait à utiliser useEffect
pour créer votre identifiant au premier rendu et le stocker dans l'état:
const id = uuid(); const Dialog = () => { return <div>Hello Dialog</div> }
Donner un tableau vide comme Le deuxième paramètre de useEffect
l'empêche de se déclencher plus d'une fois.
Mais une autre solution extrêmement simple pourrait être de simplement ... le créer en dehors de votre composant:
const Dialog = () => { const [id, setId] = useState(null); useEffect(() => { setId(uuid()) }, []) return <div>Hello Dialog</div> }
Ou cela peut aussi être const [id, setId] = useState (uuid ())
.
@norbitrial Eh bien, j'y ai pensé, mais cela voudrait dire que le hook useState
va être appelé avec une valeur différente à chaque rendu puisque uuid
sera exécuté à chaque fois. Je ne devrais normalement pas avoir d'effets secondaires, mais comme je n'en suis pas sûr, je ne l'ai pas inclus
Je suppose que si vous passez une valeur à useState
, elle sera conservée jusqu'à la durée de vie du composant donc techniquement, elle ne sera pas modifiée lors du rendu. Il sera modifié une fois que setId
sera appelé.
Évitez cette solution extrêmement simple, sauf si vous êtes sûr qu'il n'y aura pas plus d'un seul composant 'Dialog' monté en même temps ou que le caractère aléatoire de l'Id n'a pas d'importance (dans ce cas, vous n'avez pas à utiliser uuid) .
Notez également qu'avec cette méthode useEffect, id sera nul dans le premier rendu car useEffect s'exécute après le rendu.
Toute propriété d'instance devient pratiquement une référence, et vous accéderiez à idRef.current
dans ce cas pour l'id
function Dialog() { const idRef = useRef(uuid()) return <div>Hello Dialog</div> }
Vous pouvez le stocker dans l'état:
const id = useRef(null); if(!id.current) { // initialise id.current = uuid(); } // To access itâs value console.log(id.current);
Vous pouvez également le stocker dans React ref:
const [id] = useState(uuid()); // uuid will be called in every render but only the first one will be used for initiation // or using lazy initial state const [id] = useState(() => uuid()); // uuid will only be called once for initiation
Merci à tous, vos solutions fonctionnent bien. J'essaye aussi cette solution et je la trouve OK aussi: remplacez this.id
par Dialog.id
. Y a-t-il un inconvénient à cette solution?
Vous pouvez utiliser
React.useRef
. Si votre référencecurrent
est vide, essayez de le définir sur unuuid ()
, sinon cela signifie que vous en avez déjà un et que vous pouvez l'ignorer.