Javascript 为什么auth().OnAuthStateChangedTrigger被多次触发?

Javascript 为什么auth().OnAuthStateChangedTrigger被多次触发?,javascript,firebase,react-native,authentication,Javascript,Firebase,React Native,Authentication,问题是,通过启动有问题的页面,该方法会被调用多次。只要我单击RightContent,相同的方法就会被调用更多次。我尝试用一个布尔变量作为标志来求解,但程序似乎避免了这种情况。 守则: auth().onAuthStateChanged((user) => { const preferredArtistRef = firestore().collection('preferredArtist') if (user) { isSignedUser(true) setUid(user

问题是,通过启动有问题的页面,该方法会被调用多次。只要我单击
RightContent
,相同的方法就会被调用更多次。我尝试用一个布尔变量作为标志来求解,但程序似乎避免了这种情况。 守则:

auth().onAuthStateChanged((user) => { 
const preferredArtistRef = firestore().collection('preferredArtist')
if (user) {
  isSignedUser(true)
  setUid(user.uid)
  preferredArtistRef  //<--- to check if the page is already in favorites
    .get()
    .then(querySnapshot => {
      querySnapshot.forEach(documentSnapshot => {
        setDocumentId(documentSnapshot.id)
        if (documentSnapshot.data().uid == uid && documentSnapshot.data().artist == nameArtist) {
          setPreferred(true)
          console.log('add')  //<--- this appears many times in the console
        }
      })
    })
} else {
  isSignedUser(false)
}
  });
编辑:我添加所有代码:

import React, { useEffect, useState } from 'react';
import { StyleSheet, Text, ActivityIndicator, View, Image, Dimensions, FlatList } from 'react-native';
import { StackActions } from '@react-navigation/native';
import { Card } from 'react-native-paper';
import auth from '@react-native-firebase/auth';
import firestore from '@react-native-firebase/firestore';
import FontAwesome from 'react-native-vector-icons/FontAwesome';
import FontAwesome5 from 'react-native-vector-icons/FontAwesome5';
import AntDesign from 'react-native-vector-icons/AntDesign';

const ArtistScreen = ({ route, navigation }) => {  //in caso di problemi torna function

  const textArtist = route.params;

  const screen = Dimensions.get("screen");

  const geniusUrl = 'https://api.genius.com';

  const [isLoading, setLoading] = useState(true);

  const [nameArtist, setNameArtist] = useState([]);
  const [picArtist, setPicArtist] = useState([]);
  const [bioArtist, setBioArtist] = useState([]);
  const [bioNotFound, setBioNotFound] = useState(true);

  const [topSongJson, setTopSongJson] = useState([]);
  const [idArtist, setIdArtist] = useState([]);

  auth().onAuthStateChanged((user) => {    //<-------
    const preferredArtistRef = firestore().collection('preferredArtist')
    if (user) {
      isSignedUser(true)
      setUid(user.uid)
      preferredArtistRef
        .get()
        .then(querySnapshot => {
          querySnapshot.forEach(documentSnapshot => {
            setDocumentId(documentSnapshot.id)
            if (documentSnapshot.data().uid == uid && documentSnapshot.data().artist == nameArtist) {
              setPreferred(true)
              console.log('add')
            }
          })
        })
    } else {
      isSignedUser(false)
    }
  });

  const [uid, setUid] = useState();
  const [documentId, setDocumentId] = useState();

  const [signedUser, isSignedUser] = useState();
  const visibleIcon = signedUser ? 30 : 0;

  const [preferred, setPreferred] = useState();
  const star = preferred ? 'star' : 'star-o';

  const RightContent = () =>  // <--------
    <FontAwesome
      name={star}
      color='#673AB7'
      size={visibleIcon}
      onPress={() => {
        const preferredArtistRef = firestore().collection('preferredArtist')
        if (preferred) {
          setPreferred(false)
          preferredArtistRef
            .doc(documentId)
            .delete()
            .then(() => {
              console.log('Artist remove')
            })
            .catch((error) => alert(error))
        } else {
          setPreferred(true)
          preferredArtistRef
            .add({
              uid: uid,
              artist: nameArtist
            })
            .then(querySnapshot => {
              console.log('Artist added in prefer')
            })
            .catch((error) => alert(error))
        }
      }}
      style={styles.star}
    />

  const ButtonSong = (textArtist, textSong) => {
    navigation.dispatch(StackActions.push('Search song', { textArtist, textSong }))
  }

  useEffect(() => {
    fetch(geniusUrl + '/search?q=' + textArtist, {
      headers: { 'Authorization': 'Bearer ' + geniusToken }
    })
      .then((response) => response.json())
      .then((data) => {

        setTopSongJson(data.response.hits)

        for (const value of data.response.hits) {

          if (value.result.primary_artist.name.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase() ==
            textArtist.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().trim()) {

            setNameArtist(value.result.primary_artist.name)
            setPicArtist(value.result.primary_artist.header_image_url)
            setIdArtist(value.result.primary_artist.id)

            return fetch(geniusUrl + value.result.primary_artist.api_path, {
              headers: { 'Authorization': 'Bearer ' + geniusToken }
            })
              .then((response) => response.json())
              .then((text) => {

                var buildBio = ""
                for (const child of text.response.artist.description.dom.children) {
                  if (child == '') {
                    buildBio = buildBio.concat('\n\n')
                  }
                  else if (child.tag == 'p') {
                    for (const childP of child.children) {
                      if (typeof childP == 'string')
                        buildBio = buildBio.concat(childP)
                      else {
                        if (childP.tag == 'a') {
                          for (const childA of childP.children) {
                            if (typeof childA == 'string')
                              buildBio = buildBio.concat(childA)
                            else {
                              if (childA.tag == 'em') {
                                for (const childEM of childA.children) {
                                  if (typeof childEM == 'string')
                                    buildBio = buildBio.concat(childEM)
                                }
                              }
                            }
                          }
                        }
                        else if (childP.tag == 'em') {
                          for (const childEM of childP.children) {
                            if (typeof childEM == 'string')
                              buildBio = buildBio.concat(childEM)
                            else {
                              if (childEM.tag == 'a') {
                                for (const childA of childEM.children) {
                                  if (typeof childA == 'string')
                                    buildBio = buildBio.concat(childA)
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
                if (buildBio != "" && buildBio != "?") {
                  setBioArtist(buildBio)
                  setBioNotFound(false)
                }

              })
              .catch((error) => console.log(error))
              .finally(() => setLoading(false))
          }
        }
      })
      .catch((error) => console.log(error))
      .finally(() => setLoading(false));

  }, []);


  return (
    <View style={styles.container}>
      {isLoading ? (
        <View style={styles.loading}>
          <ActivityIndicator
            size='large'
            color='#673AB7'
          />
        </View>
      ) : (
        bioNotFound ? (
          <View style={styles.loading}>
            <Text>
              Sorry!
            </Text>
            <Text>
              Your request didin't produce any result
            </Text>
          </View>
        ) : (
          <FlatList
            ListHeaderComponent={
              <>
                <View style={styles.titleView}>
                  <Text style={styles.textTitle}>
                    {nameArtist}
                  </Text>
                  <RightContent />
                </View>
                <View
                  style={styles.titleRow}
                />
                <View style={{ padding: 10 }}>
                  <Image
                    source={{ uri: picArtist }}
                    style={[styles.image, { width: { screen }.width }]}
                  />
                  <Text style={styles.textBio}>
                    {bioArtist}
                  </Text>
                </View>
                <View style={{ paddingBottom: 20 }}>
                  <Text style={styles.titleTopSong}>
                    Top Song by {nameArtist}
                  </Text>
                  <View
                    style={styles.titleRow}
                  />
                </View>
              </>
            }
            data={topSongJson}
            keyExtractor={item => item.result.id}
            renderItem={({ item }) => (
              item.result.primary_artist.id == idArtist ?
                <View style={styles.card}>
                  <Card>
                    <Card.Title
                      title={item.result.title}
                      subtitle={item.result.primary_artist.name}
                      right={() =>
                        <FontAwesome5
                          name='headphones-alt'
                          color='#673AB7'
                          size={30}
                          onPress={() => ButtonSong(item.result.primary_artist.name, item.result.title)}
                          style={styles.headphones}
                        />
                      }
                    />
                  </Card>
                </View>
                : null
            )}
          />
        )
      )}
    </View>
  )
}


const styles = StyleSheet.create({
  // all styles
});

export default ArtistScreen;
import React,{useffect,useState}来自“React”;
从“react native”导入{样式表、文本、ActivityIndicator、视图、图像、维度、平面列表};
从'@react-navigation/native'导入{StackActions};
从“react native paper”导入{Card};
从'@react native firebase/auth'导入身份验证;
从“@react native firebase/firestore”导入firestore;
从“反应本机矢量图标/FontAwesome”导入FontAwesome;
从“反应本机向量图标/FontAwesome5”导入FontAwesome5;
从“react native vector icons/AntDesign”导入AntDesign;
const ArtistScreen=({route,navigation})=>{//in caso di problemi torna函数
const textArtist=route.params;
常量屏幕=尺寸。获取(“屏幕”);
常数geniusUrl=https://api.genius.com';
const[isLoading,setLoading]=useState(true);
const[nameArtist,setNameArtist]=useState([]);
常量[picArtist,setPicArtist]=useState([]);
常量[bioArtist,setBioArtist]=useState([]);
const[bioNotFound,setBioNotFound]=useState(true);
const[topSongJson,setTopSongJson]=useState([]);
常量[idArtist,setIdArtist]=useState([]);
auth().onAuthStateChanged((用户)=>{//{
querySnapshot.forEach(documentSnapshot=>{
setDocumentId(documentSnapshot.id)
if(documentSnapshot.data().uid==uid&&documentSnapshot.data().artist==nameArtist){
setPreferred(true)
console.log('add')
}
})
})
}否则{
isSignedUser(假)
}
});
const[uid,setUid]=useState();
const[documentId,setDocumentId]=useState();
const[signedUser,isSignedUser]=useState();
const visibleIcon=signedUser?30 : 0;
const[preferred,setPreferred]=useState();
常数星=首选?”星':'星-o';
常量RightContent=()=>/{
console.log('Artist remove')
})
.catch((错误)=>警报(错误))
}否则{
setPreferred(true)
首选艺术家
.添加({
uid:uid,
艺术家:姓名艺术家
})
.然后(querySnapshot=>{
console.log('Artist added in preference')
})
.catch((错误)=>警报(错误))
}
}}
style={style.star}
/>
const ButtonSong=(文本艺术家,文本歌曲)=>{
dispatch(StackActions.push('Search song',{textArtister,textSong}))
}
useffect(()=>{
获取(geniusrl+'/search?q='+textArtister{
标题:{‘授权’:‘持有者’+geniusToken}
})
.then((response)=>response.json())
。然后((数据)=>{
setTopSongJson(data.response.hits)
for(data.response.hits的常量值){
if(value.result.primary_artist.name.normalize(“NFD”).replace(/[\u0300-\u036f]/g,“”).toLowerCase()==
textArtister.normalize(“NFD”).replace(/[\u0300-\u036f]/g,”).toLowerCase().trim(){
SetNameArtister(value.result.primary\u artist.name)
setPicArtist(value.result.primary\u artist.header\u image\u url)
setIdArtist(value.result.primary\u artist.id)
返回获取(geniusrl+value.result.primary\u artist.api\u路径{
标题:{‘授权’:‘持有者’+geniusToken}
})
.then((response)=>response.json())
。然后((文本)=>{
var buildBio=“”
for(text.response.artist.description.dom.children的常量子级){
如果(子项=“”){
buildBio=buildBio.concat('\n\n')
}
else if(child.tag='p'){
for(const childP of child.childs){
if(typeof childP=='string')
buildBio=buildBio.concat(childP)
否则{
如果(childP.tag=='a'){
用于(儿童的常量儿童P.儿童){
if(typeof childA=='string')
buildBio=buildBio.concat(childA)
否则{
if(childA.tag==“em”){
用于(儿童的常量childEM of childA.childs){
if(typeof childEM=='string')
buildBio=buildBio.concat(childEM)
}
}
}
}
}
else if(childP.tag==“em”){
用于(儿童的常量儿童P.儿童){
if(typeof childEM=='string')
buildBio=buildBio.concat(childEM)
否则{
如果(childEM.tag=='a'){
用于(儿童的常量childA.childEM.childs){
if(typeof childA=='string')
buildBio=buildBio.concat(childA)
}
}
}
}
}
}
}
}
}
如果(buildBio!=“”&&buildBio!=“?”){
建筑艺术家(建筑生物)
SetBinotFound(假)
}
})
.catch((错误)=>console.log(错误))
.最后(()=>设置加载(fals
import React, { useEffect, useState } from 'react';
import { StyleSheet, Text, ActivityIndicator, View, Image, Dimensions, FlatList } from 'react-native';
import { StackActions } from '@react-navigation/native';
import { Card } from 'react-native-paper';
import auth from '@react-native-firebase/auth';
import firestore from '@react-native-firebase/firestore';
import FontAwesome from 'react-native-vector-icons/FontAwesome';
import FontAwesome5 from 'react-native-vector-icons/FontAwesome5';
import AntDesign from 'react-native-vector-icons/AntDesign';

const ArtistScreen = ({ route, navigation }) => {  //in caso di problemi torna function

  const textArtist = route.params;

  const screen = Dimensions.get("screen");

  const geniusUrl = 'https://api.genius.com';

  const [isLoading, setLoading] = useState(true);

  const [nameArtist, setNameArtist] = useState([]);
  const [picArtist, setPicArtist] = useState([]);
  const [bioArtist, setBioArtist] = useState([]);
  const [bioNotFound, setBioNotFound] = useState(true);

  const [topSongJson, setTopSongJson] = useState([]);
  const [idArtist, setIdArtist] = useState([]);

  auth().onAuthStateChanged((user) => {    //<-------
    const preferredArtistRef = firestore().collection('preferredArtist')
    if (user) {
      isSignedUser(true)
      setUid(user.uid)
      preferredArtistRef
        .get()
        .then(querySnapshot => {
          querySnapshot.forEach(documentSnapshot => {
            setDocumentId(documentSnapshot.id)
            if (documentSnapshot.data().uid == uid && documentSnapshot.data().artist == nameArtist) {
              setPreferred(true)
              console.log('add')
            }
          })
        })
    } else {
      isSignedUser(false)
    }
  });

  const [uid, setUid] = useState();
  const [documentId, setDocumentId] = useState();

  const [signedUser, isSignedUser] = useState();
  const visibleIcon = signedUser ? 30 : 0;

  const [preferred, setPreferred] = useState();
  const star = preferred ? 'star' : 'star-o';

  const RightContent = () =>  // <--------
    <FontAwesome
      name={star}
      color='#673AB7'
      size={visibleIcon}
      onPress={() => {
        const preferredArtistRef = firestore().collection('preferredArtist')
        if (preferred) {
          setPreferred(false)
          preferredArtistRef
            .doc(documentId)
            .delete()
            .then(() => {
              console.log('Artist remove')
            })
            .catch((error) => alert(error))
        } else {
          setPreferred(true)
          preferredArtistRef
            .add({
              uid: uid,
              artist: nameArtist
            })
            .then(querySnapshot => {
              console.log('Artist added in prefer')
            })
            .catch((error) => alert(error))
        }
      }}
      style={styles.star}
    />

  const ButtonSong = (textArtist, textSong) => {
    navigation.dispatch(StackActions.push('Search song', { textArtist, textSong }))
  }

  useEffect(() => {
    fetch(geniusUrl + '/search?q=' + textArtist, {
      headers: { 'Authorization': 'Bearer ' + geniusToken }
    })
      .then((response) => response.json())
      .then((data) => {

        setTopSongJson(data.response.hits)

        for (const value of data.response.hits) {

          if (value.result.primary_artist.name.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase() ==
            textArtist.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().trim()) {

            setNameArtist(value.result.primary_artist.name)
            setPicArtist(value.result.primary_artist.header_image_url)
            setIdArtist(value.result.primary_artist.id)

            return fetch(geniusUrl + value.result.primary_artist.api_path, {
              headers: { 'Authorization': 'Bearer ' + geniusToken }
            })
              .then((response) => response.json())
              .then((text) => {

                var buildBio = ""
                for (const child of text.response.artist.description.dom.children) {
                  if (child == '') {
                    buildBio = buildBio.concat('\n\n')
                  }
                  else if (child.tag == 'p') {
                    for (const childP of child.children) {
                      if (typeof childP == 'string')
                        buildBio = buildBio.concat(childP)
                      else {
                        if (childP.tag == 'a') {
                          for (const childA of childP.children) {
                            if (typeof childA == 'string')
                              buildBio = buildBio.concat(childA)
                            else {
                              if (childA.tag == 'em') {
                                for (const childEM of childA.children) {
                                  if (typeof childEM == 'string')
                                    buildBio = buildBio.concat(childEM)
                                }
                              }
                            }
                          }
                        }
                        else if (childP.tag == 'em') {
                          for (const childEM of childP.children) {
                            if (typeof childEM == 'string')
                              buildBio = buildBio.concat(childEM)
                            else {
                              if (childEM.tag == 'a') {
                                for (const childA of childEM.children) {
                                  if (typeof childA == 'string')
                                    buildBio = buildBio.concat(childA)
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
                if (buildBio != "" && buildBio != "?") {
                  setBioArtist(buildBio)
                  setBioNotFound(false)
                }

              })
              .catch((error) => console.log(error))
              .finally(() => setLoading(false))
          }
        }
      })
      .catch((error) => console.log(error))
      .finally(() => setLoading(false));

  }, []);


  return (
    <View style={styles.container}>
      {isLoading ? (
        <View style={styles.loading}>
          <ActivityIndicator
            size='large'
            color='#673AB7'
          />
        </View>
      ) : (
        bioNotFound ? (
          <View style={styles.loading}>
            <Text>
              Sorry!
            </Text>
            <Text>
              Your request didin't produce any result
            </Text>
          </View>
        ) : (
          <FlatList
            ListHeaderComponent={
              <>
                <View style={styles.titleView}>
                  <Text style={styles.textTitle}>
                    {nameArtist}
                  </Text>
                  <RightContent />
                </View>
                <View
                  style={styles.titleRow}
                />
                <View style={{ padding: 10 }}>
                  <Image
                    source={{ uri: picArtist }}
                    style={[styles.image, { width: { screen }.width }]}
                  />
                  <Text style={styles.textBio}>
                    {bioArtist}
                  </Text>
                </View>
                <View style={{ paddingBottom: 20 }}>
                  <Text style={styles.titleTopSong}>
                    Top Song by {nameArtist}
                  </Text>
                  <View
                    style={styles.titleRow}
                  />
                </View>
              </>
            }
            data={topSongJson}
            keyExtractor={item => item.result.id}
            renderItem={({ item }) => (
              item.result.primary_artist.id == idArtist ?
                <View style={styles.card}>
                  <Card>
                    <Card.Title
                      title={item.result.title}
                      subtitle={item.result.primary_artist.name}
                      right={() =>
                        <FontAwesome5
                          name='headphones-alt'
                          color='#673AB7'
                          size={30}
                          onPress={() => ButtonSong(item.result.primary_artist.name, item.result.title)}
                          style={styles.headphones}
                        />
                      }
                    />
                  </Card>
                </View>
                : null
            )}
          />
        )
      )}
    </View>
  )
}


const styles = StyleSheet.create({
  // all styles
});

export default ArtistScreen;
auth().onAuthStateChanged((user) => {
const ArtistScreen = ({ route, navigation }) => { 
  // ...
  useEffect(() => {
    const unsubscribe = auth.onAuthStateChanged((user) => {
      // ... etc
    });
    return unsubscribe; // This will let it clean up when the ArtistScreen unmounts
  }, []); // The empty dependency array means it will only run once, when mounting