Maison  >  Questions et réponses  >  le corps du texte

Choisir un React Hook adapté à une utilisation avec l'instantané de Firestore

<p>J'utilise beaucoup les instantanés Firestore dans mon application React Native. J'ai également utilisé des hooks React. Le code ressemble à ceci : </p> <pre class="brush:php;toolbar:false;">useEffect(() => { someFirestoreAPICall().onSnapshot(snapshot => { // Lors du chargement initial du composant, ajoutez toutes les données chargées à l'état. // Lorsque les données sur Firestore changent, nous recevons des mises à jour dans ce rappel, // Puis mettez à jour l'interface utilisateur en fonction de l'état actuel });; }, []);</pre> <p>Au début, je pensais que <code>useState</code> était le meilleur crochet pour stocker et mettre à jour l'interface utilisateur. Cependant, selon les paramètres de mon hook <code>useEffect</code>, qui est fourni avec un tableau de dépendances vide, lorsque le rappel d'instantané est déclenché et que j'essaie de modifier l'état actuel avec de nouvelles modifications, l'état actuel n'est pas défini. . Je pense que cela est dû aux fermetures. J'ai pu résoudre ce problème en utilisant <code>useRef</code> et <code>forceUpdate()</code> <pre class="brush:php;toolbar:false;">const dataRef = useRef(initialData); const [, updateState] = React.useState(); const forceUpdate = useCallback(() => updateState({}), []); useEffect(() => { someFirestoreAPICall().onSnapshot(snapshot => { // Si des données d'instantané sont ajoutées dataRef.current.push(newData) Forcer la mise à jour() //Si les données de l'instantané sont mises à jour dataRef.current.find(e => certaines conditions) = updateData Forcer la mise à jour() });; }, []); retour( // JSX utilisant dataRef.current )</pré> <p>Ma question est la suivante : est-ce que j'utilise correctement <code>useRef</code> et <code>forceUpdate</code> différemment de <code>useState</code> J'ai l'impression que mettre à jour le hook <code>useRef</code> et appeler <code>forceUpdate()</code> En essayant d'utiliser <code>useState</code>, j'ai essayé d'ajouter la variable d'état au tableau de dépendances, mais cela a entraîné une boucle infinie. Je souhaite initialiser la fonction d'instantané une seule fois et souhaite que les données avec état du composant soient mises à jour au fil du temps à mesure que le backend change (déclenché dans le rappel onSnapshot). </p>
P粉555682718P粉555682718398 Il y a quelques jours461

répondre à tous(2)je répondrai

  • P粉806834059

    P粉8068340592023-08-25 12:43:07

    Ce sera mieux si vous combinez useEffect et useState. useEffect est responsable de la configuration et de la désactivation de l'écouteur, et useState est uniquement responsable des données dont vous avez besoin.

    const [data, setData] = useState([]);
    
    useEffect(() => { 
           const unsubscribe = someFirestoreAPICall().onSnapshot(snap => {
             const data = snap.docs.map(doc => doc.data())
             this.setData(data)
           });
    
           //记得在卸载组件时取消实时监听器,否则会造成内存泄漏
           return () => unsubscribe()
    }, []);

    Ensuite, vous pouvez référencer directement les "données" dans le hook useState de votre application.

    répondre
    0
  • P粉165522886

    P粉1655228862023-08-25 12:37:51

    Un simple useEffect a fonctionné pour moi, je n'ai pas besoin de créer une fonction d'assistance ou quoi que ce soit du genre,

    useEffect(() => {
            const colRef = collection(db, "data")
            //real time update
            onSnapshot(colRef, (snapshot) => {
                snapshot.docs.forEach((doc) => {
                    setTestData((prev) => [...prev, doc.data()])
                    // console.log("onsnapshot", doc.data());
                })
            })
        }, [])

    Un simple useEffect fonctionne pour moi, je n'ai pas besoin de créer de fonctions d'assistance ou quelque chose comme ça,

    useEffect(() => {
            const colRef = collection(db, "data")
            //实时更新
            onSnapshot(colRef, (snapshot) => {
                snapshot.docs.forEach((doc) => {
                    setTestData((prev) => [...prev, doc.data()])
                    // console.log("onsnapshot", doc.data());
                })
            })
        }, [])

    répondre
    0
  • Annulerrépondre