extraData 钩子不适用于 2 个 flatLists 之一
Posted
技术标签:
【中文标题】extraData 钩子不适用于 2 个 flatLists 之一【英文标题】:extraData hook not working for one of 2 flatLists 【发布时间】:2021-09-06 15:35:48 【问题描述】:所以我正在尝试为我的网站构建一个新闻提要阅读器。它非常基本,只有 2 个平面列表。一个垂直列出文章,另一个水平列出网站。单击水平项目时,它会更新 2 个不同的状态设置。这 2 个设置被设置为 flatLists 的 extraData。水平的会在按下后重新渲染,而垂直的则不会。
onPress 正在更新站点和 selectedId 状态,当站点 flatList 重新呈现并显示背景颜色更改时,artile flatList 不会使用新提要重新呈现。
这里是代码。
import StatusBar from 'expo-status-bar';
import React, useState, useEffect from 'react';
import StyleSheet, Text, Image, View, FlatList, TouchableOpacity, Avatar, Dimensions from 'react-native';
import Header from './components/header';
import Article from './components/article';
export default function App()
const [isLoading, setLoading] = useState(true);
const [articles, setArticles] = useState([]);
const [site, setSite] = useState('https://minedhash.com/feed');
useEffect(() =>
fetch('https://api.rss2json.com/v1/api.json?rss_url='+site)
.then((response) => response.json())
.then((json) => setArticles(json.items))
.catch((error) => console.error(error))
.finally(() => setLoading(false));
, []);
const [selectedId, setSelectedId] = useState(2);
const nftImg = require('assets/NFT.png');
const mhImg = require('assets/MH.png');
const cntImg = require('assets/CNT.png');
const sntImg = require('assets/SNT.png');
const entImg = require('assets/ENT.png');
const bscImg = require('assets/BSC.png');
const ethImg = require('assets/ETH.png');
const fafImg = require('assets/FAF.png');
const pntImg = require('assets/PNT.png');
const cenImg = require('assets/CEN.png');
const siteList = [
'id': 1, 'name': 'NFT News Today', 'avatar': nftImg, 'color': '#ffffff', 'bgcolor': '#6856dd', 'url': 'https://nftnewstoday.com/feed',
'id': 2, 'name': 'Mined Hash', 'avatar': mhImg, 'color': '#000000', 'bgcolor': '#ff5757', 'url': 'https://minedhash.com/feed',
'id': 3, 'name': 'Cardano News Today', 'avatar': cntImg, 'color': '#000000', 'bgcolor': '#3cc8c8', 'url': 'https://cardanonewstoday.com/feed',
'id': 4, 'name': 'Solana News Today', 'avatar': sntImg, 'color': '#000000', 'bgcolor': '#7783d4', 'url': 'https://solananewstoday.com/feed',
'id': 5, 'name': 'Elrond News Today', 'avatar': entImg, 'color': '#ffffff', 'bgcolor': '#090223', 'url': 'https://elrondnews.com/feed',
'id': 6, 'name': 'BSC Chain', 'avatar': bscImg, 'color': '#ffffff', 'bgcolor': '#2b2e35', 'url': 'https://bscchainnews.com/feed',
'id': 7, 'name': 'Ethereum News Today', 'avatar': ethImg, 'color': '#000000', 'bgcolor': '#d8cd51', 'url': 'https://ethereumnewstoday.net/feed',
'id': 8, 'name': 'Finance and Freedom', 'avatar': fafImg, 'color': '#ffffff', 'bgcolor': '#0000fe', 'url': 'https://financeandfreedom.org/feed',
'id': 9, 'name': 'Polkadat News Today', 'avatar': pntImg, 'color': '#ffffff', 'bgcolor': '#1e1e1e', 'url': 'https://polkadotnewstoday.com/feed',
'id': 10, 'name': 'Crypto Exchange News Today', 'avatar': cenImg, 'color': '#ffffff', 'bgcolor': '#0277bd', 'url': 'https://cryptoexchangenews.net/feed',
]
const Item = ( item, onPress, backgroundColor, textColor ) => (
<TouchableOpacity onPress=onPress style=[styles.site, backgroundColor]>
<Image style=styles.tinyLogo source=item.avatar resizeMode='cover' />
<Text style=[styles.title, textColor]>item.name</Text>
</TouchableOpacity>
);
const renderItem = ( item ) =>
const backgroundColor = item.id == selectedId ? "#373361" : "#05003a";
const color = 'white';
return (
<Item
item=item
onPress=function()
setSelectedId(item.id);
setSite(item.url);
backgroundColor= backgroundColor
textColor= color
/>
);
;
return (
<View style=styles.container>
/* header */
<Header />
<View style=styles.content>
<View style=styles.articleList>
/* Content */
isLoading ? <Text>Loading...</Text> :
( <FlatList
data=articles
renderItem=( item ) => (
<Article item=item/>
)
keyExtractor=(item, index) => index.toString()
extraData=site
/>
)
</View>
</View>
<View style=styles.siteBar>
/* siteBar */
<FlatList
horizontal
data=siteList
renderItem=renderItem
keyExtractor=(item) => item.id.toString()
extraData=selectedId
/>
</View>
<StatusBar style='light' />
</View>
);
const styles = StyleSheet.create(
container:
flex: 1,
backgroundColor: '#fff',
,
content:
paddingLeft: 20,
paddingRight: 20,
,
articleList:
marginTop: 10,
marginBottom: 10,
height: Dimensions.get('window').height - 190
,
siteBar:
height: 140,
width: Dimensions.get('window').width,
backgroundColor: '#fff',
,
site:
height: 200,
width: 110,
marginLeft: 5,
padding: 5,
borderColor: '#fff',
borderWidth: 1,
borderRadius: 10,
textAlign: 'center',
,
title:
textAlign: 'center',
,
tinyLogo:
height: 90,
width: 90,
marginLeft: 5,
marginTop: 5
);
【问题讨论】:
好的,添加更多信息。我添加了拉动刷新,在通过按钮更改网站后,我必须拉动刷新两次才能获取新提要? 【参考方案1】:根据代码观察,我可以看到 useEffect 代码中可能存在依赖问题。
尝试在 useEffect 依赖列表中添加站点依赖。
试一下。
useEffect(() =>
fetch('https://api.rss2json.com/v1/api.json?rss_url=' + site)
.then((response) => response.json())
.then((json) => setArticles(json.items))
.catch((error) => console.error(error))
.finally(() => setLoading(false))
, [site])
而不是
useEffect(() =>
fetch('https://api.rss2json.com/v1/api.json?rss_url=' + site)
.then((response) => response.json())
.then((json) => setArticles(json.items))
.catch((error) => console.error(error))
.finally(() => setLoading(false))
, [])
【讨论】:
以上是关于extraData 钩子不适用于 2 个 flatLists 之一的主要内容,如果未能解决你的问题,请参考以下文章
React 钩子表单不适用于来自 reactstrap 的输入
Woocommerce 订单状态挂起钩子不适用于 PayPal 交易