Finalmente lo implemente, sin embargo, tengo algunas dudas, primero la solucion final es esta:
ArtistBox.js
exportdefault classArtistBoxextendsComponent{ state ={linked:false,likeCount:0,commentCount:0}componentWillMount(){this.getArtistRef().on('value',snapshot=>{const artist = snapshot.val()const{ uid }= firebaseAuth.currentUserif(artist){this.setState({liked: artist.likes&& artist.likes[uid],likeCount: artist.likeCount})}})this.countComments()}componentDidMount(){this.getArtistCommentsRef().on('child_added',this.countComments)}countComments=()=>{let commentCount =0;this.getArtistCommentsRef().once('value',snapshot=>{ snapshot.forEach(comment=>{ commentCount = commentCount +1})this.setState({commentCount: commentCount
})})}handlePress=()=>{const{ id }=this.props.artistthis.toggleLike(!this.state.liked)}getArtistRef=()=>{const{ id }=this.props.artistreturn firebaseDatabase.ref(`artist/${id}`)}getArtistCommentsRef=()=>{const{ id }=this.props.artistreturn firebaseDatabase.ref(`comments/${id}`)}toggleLike=(liked)=>{const{ uid }= firebaseAuth.currentUserthis.getArtistRef().transaction(function(artist){if(artist){if(artist.likes&& artist.likes[uid]){ artist.likeCount--; artist.likes[uid]=null;}else{ artist.likeCount++;if(!artist.likes){ artist.likes={};} artist.likes[uid]=true;}}return artist ||{likeCount:1,likes:{[uid]:true}};});}render(){const{image, name, comments}=this.props.artist;const{ likeCount, commentCount }=this.state;const likeIcon =this.state.liked?<Iconname="ios-heart"size={30}color="#e74c3c"/>:<Iconname="ios-heart-outline"size={30}color="gray"/>;return(<Viewstyle={styles.artistBox}><Imagestyle={styles.image}source={{uri:image}}/><Viewstyle={styles.info}><Textstyle={styles.name}>{name}</Text><Viewstyle={styles.row}><Viewstyle={styles.iconContainer}><TouchableOpacityonPress={this.handlePress}>{likeIcon}</TouchableOpacity><Textstyle={styles.count}>{likeCount}</Text></View><Viewstyle={styles.iconContainer}><Iconname="ios-chatboxes-outline"size={30}color="gray"/><Textstyle={styles.count}>{commentCount}</Text></View></View></View></View>);}}
ArtistDetailView.js
exportdefaultclassArtistDetailViewextendsComponent{ state ={comments:[]}handleSend=()=>{const{ text }=this.stateconst{uid, photoURL}= firebaseAuth.currentUserconst artistCommentsRef =this.getArtistCommentsRef()var newCommentRef = artistCommentsRef.push() newCommentRef.set({ text,userPhoto: photoURL, uid
});this.setState({text:''})}getArtistCommentsRef=()=>{const{ id }=this.props.artistreturn firebaseDatabase.ref(`comments/${id}`)}handleChangeText=(text)=>this.setState({text})componentDidMount(){this.getArtistCommentsRef().on('child_added',this.addComment)this.getArtistCommentsRef().once('value',snapshot=>{let comments ={comments:[]} snapshot.forEach(comment=>{ comments.comments= comments.comments.concat(comment.val())})this.setState({comments: comments.comments})})}addComment=(data)=>{const comment = data.val()this.setState({comments:this.state.comments.concat(comment)})}componentWillUnmount(){this.getArtistCommentsRef().off('child_added',this.addComment)}render(){const artist =this.props.artistconst{ comments }=this.statereturn(<View style={styles.container}><ArtistBox artist={artist}/><CommentList comments={comments}/><View style={styles.inputContainer}><TextInput style={styles.input} value={this.state.text} placeholder="Opina sobre este artista" onChangeText={this.handleChangeText}/><TouchableOpacity onPress={this.handleSend}><Icon name="ios-send-outline" size={30} color="gray"/></TouchableOpacity></View></View>);}}
Pregunta 1:
Ahora cuando entro en el detail view y regreso, al ejecutar cualquier accion que cambio el state como el like o agregar un comentario tengo el warning de “SetState can only update a mounted or mounting component…” funciona bien pero sale ese warning, que estoy haciendo mal?
Pregunta 2:
me gustaria entender por que cuando agrego esto en el ArtistBox.js:
Perdí la funcionalidad de Real-time-database pero sí se muestra bien la cantidad de comentarios.
En el archivo src/ArtistBox.js hice lo siguiente, dentro de componentWillMount() agregué la siguiente porción de código:
let sum =0this.getArtistCommentsRef().once('value',snapshot=>{ snapshot.forEach(comment=>{ sum = sum +1})this.setState({commentCount: sum
})})
En la definición del estado le agregué también commentCount: 0, y en la vista usé esa variable de estado.
Una pregunta, así como teníamos que hacer unsubscribe del evento child_add para ver la lista de comentarios, que sucede con el evento value, también deberíamos hacer unsubscribe en el componentWillUnmount() ?
Gracias, saludos!
Hola Juan, probablemente al suscribirse a un evento que se ejecutará por única vez como es el caso de once no haga falta. Imagino que al hacerse la llamada, debe desuscribirse automáticamente.
De todas formas, podrías investigarlo con más detalle y comentar al resto si esto es así efectivamente 😉
Creo que es mejor crear un contador de comentarios en el artista
asi:
Hola tengo una pregunta alguien me puede ayudar?
estoy creando un nuevo registro en la base de datos que me funciona muy bien por que cada vez que un usuario crea un comentario el actualiza el registro y le suma uno ala cantidad de comentarios del artista, cuando consulto la cantidad de comentarios en el
componentWillMount()
me los trae pero solo cuando se recarga la aplicación supongo que es por que se ejecuta una sola vez, la pregunta es si hay algo en reactnative que este escuchando todo el tiempo para que actualice la cantidad de comentarios en el artixBox gracias.
Adjunto el codigo que esta agregando la cantidad de comentarios ala base de datos en el archivo artistDetail.js.
Creo que es porque estas “escuchando” cuando se agrega una nueva cantidad de comentarios (‘child_added’) y en realidad tendrías que escuchar cuando se modifica un valor ‘value’ o ‘child_changed’, porque con cada suma que le haces al valor le estas cambiando el valor a “cantidadComentarios”, proba con eso quizá te funcione 😉
Listo resuelto ya tengo mi contador de comentarios funcioanando al pelo.
Ayuda
Copié el método de getArtistCommentsRef en ArtisBox para poder obtener el listado de comentarios en base al id del artist, y así obtener la cantidad, al usarlo dentro del componentWillMount funciona bien, pero ya no me llega a cargar todos los comentarios (solo me trae el último)
Estoy yendo por buen camino o cual sería lo mejor 😃
Es dificil saber si no podemos ver tu codigo.
A mi me pasa lo mismo que a @GroverJTB si obtengo la cantidad desde el ArtistDetailView, todo bien… Me muestra todos los comentarios y la cantidad, pero con el detalle de que si lo hago desde el ArtistDetailView solo se muestran cuando estoy en la pantalla de Detalle… Sigo pensando y buscando alguna manera que ande todo xD