【问题标题】:React UseState hook causing infinite loop反应 UseState 钩子导致无限循环
【发布时间】:2020-03-25 12:35:34
【问题描述】:

我正在使用 ReactJs 每 5 秒抓取一次 RSS 新闻提要,将其转换为 JSON 字符串以在网页上呈现。但是,我同时使用 useEffect 和 useState 挂钩,因为我在 useState 挂钩变量中传递 JSON 字符串。它有点工作,但它会产生一个无限循环。我搜索了堆栈溢出中提供的修复程序,但找不到确切的问题。这是我的代码 sn-p。'

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

【问题讨论】:

  • 那是因为您在每次渲染时都无条件地调用setFeed(通过调用parseString)。这会导致另一个渲染(状态更改)和另一个调用 setFeed..
  • 你最好将解析逻辑移动到thunk并摆脱组件中的状态

标签: reactjs react-hooks


【解决方案1】:

只有在新道具发生变化时才需要解析新闻。添加另一个 useEffect 与 news 作为依赖项,以便在新闻更改时调用它,然后在那里更新您的状态。

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

【讨论】:

  • 改用 JSON.stringify() 更容易
猜你喜欢
  • 2021-04-10
  • 1970-01-01
  • 1970-01-01
  • 2020-10-27
  • 2021-03-11
  • 2021-11-11
  • 2021-01-28
  • 2021-10-05
  • 2020-03-05
相关资源
最近更新 更多