React Native - State cambió en child, ¿cómo actualizar Parent?
Actualmente estoy cambiando el estado en mi componente secundario y ahora quiero actualizar a mi padre. Inicialmente, estoy pasando datos del padre al niño y luego en el niño estoy cambiando el estado. cuando hago eso, no sucede nada en la aplicación porque el padre todavía no está actualizado, pero cuando vuelvo a cargar la aplicación, se actualizan los cambios que se realizaron.
También estoy usando la navegación de reacción para pasar de la pantalla principal a la pantalla secundaria.
Aquí está mi código:
Pantalla de padres:
function PostsScreen({navigation}) {
const [posts, setPosts] = useState([]);
const [error, setError] = useState(false);
const [loading, setLoading] = useState(false);
const loadPosts = async () => {
setLoading(true);
const response = await postsApi.getPosts();
setLoading(false);
if (!response.ok) return setError(true);
setError(false);
setPosts(response.data);
};
useEffect(() => {
loadPosts();
}, []);
return(
<ActivityIndicator visible={loading} />
<FlatList
data={posts}
keyExtractor={(post) => post.id.toString()}
renderItem={({ item }) => (
<Card
title={item.title}
subTitle={item.subTitle}
onPress={() =>
navigation.navigate(routes.POST_DETAILS,item)}
/>
)}
/>
);
}
Pantalla infantil:
function PostDetailsScreen({ route }) {
const post = route.params;
const { user} = useAuth();
const [addedToLikes, setAddedToLikes] = useState(post.isLiked);
const[likesCount,setLikesCount]=useState(post.likesCount)
const addToLikes = (PostId,userId) => {
postsApi.likePost({PostId,userId});
setAddedToLikes(!addedToLikes);
};
let show_likes="";
if(addedToLikes){
show_likes=(likesCount >1)?(("Liked by you")+" and "+(likesCount - 1)+((likesCount ==2)?( "
other"):(" others"))):("Liked by you");
}else if(likesCount >0){
show_likes=(likesCount ==1)?(likesCount+ " like"):(likesCount + " likes");
}
return(
<TouchableOpacity onPress={() => {addToLikes(post.id,user.id)}}>
{addedToLikes?<MaterialCommunityIcons
name="heart"
/>:<MaterialCommunityIcons
name="heart-outline"
/>}
</TouchableOpacity>
<View><TextInput>{show_likes}</TextInput></View>
)}
¿Cómo actualizo si una publicación tiene Me gusta y cuenta Me gusta en el componente principal?
Además, no estoy usando Redux.
Actualización :
Intenté hacer lo siguiente pero sigo recibiendo un error.
Pantalla de padres:
function PostsScreen({ navigation }) {
const [posts, setPosts] = useState([]);
const [error, setError] = useState(false);
const [loading, setLoading] = useState(false);
const loadPosts = async () => {
setLoading(true);
const response = await postsApi.getPosts();
setLoading(false);
if (!response.ok) return setError(true);
setError(false);
setPosts(response.data);
};
useEffect(() => {
loadPosts();
}, []);
const [addedToLikes, setAddedToLikes] = useState(post.isLiked);
const addToLikes = (PostId, userId) => {
postsApi.likePost({ PostId, userId });
setAddedToLikes(!addedToLikes);
};
const { user } = useAuth();
return (
<React.Fragment>
<ActivityIndicator visible={loading} />
<FlatList
data={posts}
keyExtractor={post => post.id.toString()}
renderItem={({ item }) => (
<Card
title={item.title}
subTitle={item.subTitle}
onPress={() => navigation.navigate(routes.POST_DETAILS, item)}
/>
)}
/>
<PostDetailsScreen addToLikes={addToLikes(posts.id, user.id)} />
</React.Fragment>
);
}
Pantalla infantil:
function PostDetailsScreen({ route, addedToLikes, addToLikes }) {
const post = route.params;
const [likesCount, setLikesCount] = useState(post.likesCount);
let show_likes = "";
if (addedToLikes) {
show_likes =
likesCount > 1
? "Liked by you" + " and " + (likesCount - 1) + (likesCount == 2 ? " other" : " others")
: "Liked by you";
} else if (likesCount > 0) {
show_likes = likesCount == 1 ? likesCount + " like" : likesCount + " likes";
}
return (
<React.Fragment>
<TouchableOpacity
onPress={() => {
addToLikes;
}}
>
{addedToLikes ? <MaterialCommunityIcons name="heart" /> : <MaterialCommunityIcons name="heart-outline" />}
</TouchableOpacity>
<View>
<TextInput>{show_likes}</TextInput>
</View>
</React.Fragment>
);
}
Respuestas
Sin usar alguna forma de estado compartido como Redux, la mejor manera de lograr el resultado que busca es decidir la estructura de su componente.
Parece que tienes una estructura como esta:
Padre (no sabe sobre likes) -> Niño (sabe sobre likes)
Pero quieres algo como esto:
Padre (conoce likes) -> Niño (interacción con likes)
Por lo tanto, recomiendo tener stateen el componente principal un seguimiento de isLikedy likesCount. El padre también pasará un controlador de método al componente hijo, como addToLikes(post.id,user.id).
Código de ejemplo:
import React from 'react';
class Parent extends React.Component{
constructor(props){
super(props);
this.state = {
data: null
}
}
handleCallback = (childData) =>{
this.setState({data: childData})
}
render(){
const {data} = this.state;
return(
<div>
<Child parentCallback = {this.handleCallback}/>
{data}
</div>
)
}
}
class Child extends React.Component{
onTrigger = (event) => {
this.props.parentCallback("Data from child");
event.preventDefault();
}
render(){
return(
<div>
<form onSubmit = {this.onTrigger}>
<input type = "submit" value = "Submit"/>
</form>
</div>
)
}
}
export default Parent;