简体   繁体   English

extraData 钩子不适用于 2 个 flatLists 之一

[英]extraData hook not working for one of 2 flatLists

So I'm trying to build a news feed reader for my websites.所以我正在尝试为我的网站构建一个新闻提要阅读器。 it's pretty basic just 2 flatLists.它非常基本,只有 2 个 flatLists。 One vertical that lists the articles, the other horizontal that lists the sites.一个垂直列出文章,另一个水平列出站点。 When clicking on the horizontal items it is updating 2 different state settings.单击水平项目时,它会更新 2 个不同的状态设置。 These 2 settings are set as extraData for the flatLists.这 2 个设置被设置为 flatLists 的 extraData。 The horizontal one rerenders after a press but the vertical one doesn't.按下后,水平的会重新渲染,但垂直的不会。

The onPress is updating both the site and selectedId states and while the sites flatList rerenders and shows the background color change, the artile flatList does not rerender with the new feed. onPress 正在更新站点和 selectedId 状态,当站点 flatList 重新呈现并显示背景颜色更改时,artile flatList 不会使用新提要重新呈现。

Here is the code.这是代码。

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
  }
});

As per the code observation, I can see there might dependency issue in useEffect code.根据代码观察,我可以看到 useEffect 代码中可能存在依赖问题。

Have a try by adding site dependency in the useEffect dependency list.通过在 useEffect 依赖项列表中添加站点依赖项来尝试一下。

try ex.试试前

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])

instead of代替

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))
  }, [])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM