React Native-子の状態が変更されました。親を更新する方法は?
Nov 25 2020
現在、子コンポーネントの状態を変更していますが、親を更新したいと思います。最初は、親から子にデータを渡し、次に子で状態を変更します。これを行うと、親がまだ更新されていないためアプリで何も起こりませんが、アプリをリロードすると、加えられた変更が更新されます。
また、反応ナビゲーションを使用して、親画面から子画面に移動しています。
これが私のコードです:
親画面:
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)}
/>
)}
/>
);
}
子画面:
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>
)}
親コンポーネントの投稿がisLikedでlikesCountの場合、どうすれば更新できますか?
また、私はReduxを使用していません。
更新:
次のことを試しましたが、それでもエラーが発生し続けます。
親画面:
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>
);
}
子画面:
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>
);
}
回答
1 LeslieAlldridge Nov 25 2020 at 08:53
Reduxなどの何らかの形式の共有状態を使用せずに、目的の結果を達成するための最良の方法は、コンポーネントの構造を決定することです。
次のような構造になっているようです。
親(知らないlikes
)->子(知っているlikes
)
しかし、あなたはこのようなものを望んでいます:
親(知っているlikes
)->子(との相互作用likes
)
したがって、私はあなたを持つお勧めstate
の親コンポーネントキープトラックにisLiked
とlikesCount
。親は、メソッドハンドラーをaddToLikes(post.id,user.id)
。などの子コンポーネントにも渡します。
コード例:
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;