簡體   English   中英

React UseState 掛鈎導致無限循環

[英]React UseState hook causing infinite loop

我正在使用 ReactJs 每 5 秒抓取一個 RSS 新聞提要,將其轉換為 JSON 字符串以將其呈現在網頁上。 但是,我同時使用 useEffect 和 useState 掛鈎,因為我在 useState 掛鈎變量中傳遞了 JSON 字符串。 它有點工作,但它會產生無限循環。 我搜索了堆棧溢出中提供的修復程序,但找不到確切的問題。 這是我的代碼片段。

import React, {useEffect, useState} from 'react';
import Carousel from 'react-bootstrap/Carousel';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import {getNews} from "../../actions/news";
import Parser from 'rss-parser';

const NewsCarousel = ({getNews, news: {news, loading} }) => {

    const [getFeed, setFeed] = useState({
        feed: ''
    });

    useEffect(() => {
        const interval = setInterval(() => {
            getNews();
        }, 5000);
        return () => clearInterval(interval);
    }, [getNews]);


    const { feed } = getFeed;
    const newsFeed = feed => setFeed({ ...getFeed, feed: feed });

    let parser = new Parser();
    parser.parseString(news, function(err, feed){
        if (!err) {
            newsFeed(feed);
        } else {
            console.log(err);
        }

    });

    console.log(feed);
    return (
        <div className="dark-overlay">
        </div>
    );
};


NewsCarousel.propTypes = {
    getNews: PropTypes.func.isRequired,
    news: PropTypes.object.isRequired
};

const mapStateToProps = state => ({
    news: state.news
});

export default connect(mapStateToProps, {getNews}) (NewsCarousel);

當我 console.log 我的 feed 變量時,就是我在控制台中看到無限日志的時候。 下面是我的 getNews 動作

import axios from 'axios';
import { GET_NEWS, NEWS_FAIL } from "./types";

export const getNews = () => async dispatch => {
  try{
     const res = await axios.get('https://www.cbc.ca/cmlink/rss- 
     topstories');
     dispatch({
        type: GET_NEWS,
        payload: res.data
     })
} catch(err) {
    dispatch({
        type: NEWS_FAIL,
        payload: { msg: err}
    })
}
};

只有當新道具有變化時,你才需要解析你的新聞。 添加另一個 useEffect 並將新聞作為依賴項,以便在新聞更改時調用它,然后在那里更新您的狀態。

import React, {useEffect, useState} from 'react';
import Carousel from 'react-bootstrap/Carousel';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import {getNews} from "../../actions/news";
import Parser from 'rss-parser';

const NewsCarousel = ({getNews, news: {news, loading} }) => {

    const [getFeed, setFeed] = useState({
        feed: ''
    });

    useEffect(() => {
        const interval = setInterval(() => {
            getNews();
        }, 5000);
        return () => clearInterval(interval);
    }, [getNews]);

    useEffect(() => {
      const newsFeed = feed => setFeed({ ...getFeed, feed: feed });

      const parser = new Parser();
      parser.parseString(news, function(err, feed){
        if (!err) {
            newsFeed(feed);
        } else {
            console.log(err);
        }
      });
    }, [news]);

    return (
        <div className="dark-overlay">
        </div>
    );
};


NewsCarousel.propTypes = {
    getNews: PropTypes.func.isRequired,
    news: PropTypes.object.isRequired
};

const mapStateToProps = state => ({
    news: state.news
});

export default connect(mapStateToProps, {getNews}) (NewsCarousel);

您可以在此處使用Redux鈎子useDispatch防止無限循環。

而不是傳遞的getNewsNewsCarousel通過組件connect高階組件,您可以使用的useDispatch鈎。

例如:

import { useDispatch } from "react-redux";
import { getNews } from "../../actions/news";

const NewsCarousel = props => {
    useEffect(() => {
        const dispatch = useDispatch();
        const interval = setInterval(() => {
            dispatch(getNews);
        }, 5000);
        return () => clearInterval(interval);
    }, [getNews]);

    // ...
}

請注意,現在getNews不是prop,而是直接從actions/news文件導入的函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM