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 交易

React Hooks 不适用于 Firebase Cloud Functions 错误:不变违规:无效的钩子调用

EasyHook 不适用于其他线程

SetWindowsHookEx 不适用于线程 ID

UITapGeatureRecogniser 不适用于 2 个标签