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