家庭组件
const Home = ({}) => {
return (
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={HomeScreen} options={HeaderOption} />
<Stack.Screen
name="Details"
component={DetailsScreen}
options={HeaderOption}
/>
</Stack.Navigator>
);
};
export default Home;
然后(相同的文件)获得了HomeScreen组件,该组件可以(正确地)呈现文章列表,它使用useEffect从API中获取文章
function HomeScreen({ navigation }) {
const [article, setArticles] = useState();
const [loadingArticle, setLoading] = useState(false);
useEffect(() => {
console.log('start Fetching');
fetchTitles();
}, []);
const fetchTitles = () => {
fetch('myURL', {
method: 'GET',
})
.then((response) => response.json())
.then((responseData) => {
setArticles(responseData);
})
.finally(() => setLoading(false));
};
const { state } = useContext(AuthContext);
return (
<View
style={{
flex: 1,
paddingTop: Constants.HEIGTH,
backgroundColor: Constants.MAIN_GREEN,
}}
>
<LogoHeader title="TITOLO APP" isHome={true} navigation={navigation} />
<View style={{ ...styles.container }}>
<FlatList
data={article}
keyExtractor={(item) => item.id.toString()}
renderItem={({ item }) => (
<TouchableOpacity
onPress={() =>
navigation.navigate('Details', {
itemId: item.id,
})
}
>
<Card>
<Card.Content>
<HTML
html={item.title.rendered}
baseFontStyle={{ fontSize: 20, color: '#adadad' }}
/>
<Paragraph>
Published on {moment(item.date).format('LL')}
</Paragraph>
</Card.Content>
<Card.Cover source={{ uri: item.jetpack_featured_media_url }} />
<Card.Content>
<HTML
html={item.excerpt.rendered}
imagesMaxWidth={Dimensions.get('window').width}
/>
</Card.Content>
</Card>
</TouchableOpacity>
)}
/>
</View>
</View>
);
}
当我单击该文章时,即使responseData是正确的,我也可以正确到达带有正确传递的id的Details,但singleArticle为“ null”:
function DetailsScreen({ route, navigation }) {
const { state } = useContext(AuthContext);
const [singleArticle, setSingleArticle] = useState(null);
const [loadingArticle, setLoadingSingle] = useState(false);
useEffect(() => {
setLoadingSingle(true);
console.log(loadingArticle); //return false (???)
fetchSingle();
}, []);
const fetchSingle = () => {
console.log('get_single');
fetch(
'myURLgetsingle?' +
route.params.itemId,
{
method: 'GET',
}
)
.then((response) => response.json())
.then((responseData) => {
console.log('setting');
console.log(responseData); //return the values i need
setSingleArticle(responseData);
console.log(singleArticle); //return null
})
.finally(() => setLoadingSingle(false));
};
console.log(singleArticle.title.rendered);
return (
<View
style={{
flex: 1,
paddingTop: Constants.HEIGTH,
backgroundColor: Constants.MAIN_GREEN,
}}
>
<LogoHeader title="" isHome={false} navigation={navigation} />
<Card style={{ ...styles.container, padding: 10 }}>
<Card.Content>
<Title>{singleArticle.title.rendered}</Title>
<Paragraph></Paragraph>
</Card.Content>
</Card>
</View>
);
}
我认为我缺少对react native的一些基本用法,我可以通过任何方式对其进行修复吗? 谢谢
答案 0 :(得分:1)
Ciao,这对于Hooks来说是完全正常的。当您致电setSingleArticle(responseData);
并尝试在下一行登录singleArticle
时,几乎可以肯定您获得了null
的值。发生这种情况是因为setSingleArticle
是异步的,并且在Hooks中,您没有这样的回调:
setSingleArticle(responseData, () => {
// here I'm sure that singleArticle was setted
// with Hooks this is impossible to do!
});
因此,结果是,在console.log(singleArticle.title.rendered);
行中,您应该收到类似“无法获取属性标题为null”的错误。由于您的singleArticle
值来自提取,因此您可以尝试修改singleArticle
的默认值,例如:
const [singleArticle, setSingleArticle] = useState({title: {rendered: ''}});
通过这种初始化,console.log(singleArticle.title.rendered);
不会失败。此行<Title>{singleArticle.title.rendered}</Title>
编辑
对于加载样式,您可以执行以下操作:
<Title>{singleArticle.title.rendered === '' ? "Loading..." : singleArticle.title.rendered}</Title>