You need to parse your news only when there is a change in new props. Add another useEffect with news as a dependency so it will be called when the news changes and then update your state there.
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);
Answer from Amit Chauhan on Stack OverflowPassing an empty array as the second argument to useEffect makes it only run on mount and unmount, thus stopping any infinite loops.
useEffect(() => {
setIngredients({});
}, []);
This was clarified to me in the blog post on React hooks at https://www.robinwieruch.de/react-hooks/
Had the same problem. I don't know why they not mention this in docs. Just want to add a little to Tobias Haugen answer.
To run in every component/parent rerender you need to use:
useEffect(() => {
// don't know where it can be used :/
})
To run anything only one time after component mount(will be rendered once) you need to use:
useEffect(() => {
// do anything only one time if you pass empty array []
// keep in mind, that component will be rendered one time (with default values) before we get here
}, [] )
To run anything one time on component mount and on data/data2 change:
const [data, setData] = useState(false)
const [data2, setData2] = useState('default value for first render')
useEffect(() => {
// if you pass some variable, than component will rerender after component mount one time and second time if this(in my case data or data2) is changed
// if your data is object and you want to trigger this when property of object changed, clone object like this let clone = JSON.parse(JSON.stringify(data)), change it clone.prop = 2 and setData(clone).
// if you do like this 'data.prop=2' without cloning useEffect will not be triggered, because link to data object in momory doesn't changed, even if object changed (as i understand this)
}, [data, data2] )
How i use it most of the time:
export default function Book({id}) {
const [book, bookSet] = useState(false)
const loadBookFromServer = useCallback(async () => {
let response = await fetch('api/book/' + id)
response = await response.json()
bookSet(response)
}, [id]) // every time id changed, new book will be loaded
useEffect(() => {
loadBookFromServer()
}, [loadBookFromServer]) // useEffect will run once and when id changes
if (!book) return false //first render, when useEffect did't triggered yet we will return false
return <div>{JSON.stringify(book)}</div>
}
useState setting an infinite loop
Infinite loop with useState + useRecoilState
reactjs - React useState Causing an infinite loop - Stack Overflow
useState Render Infinite Loop
Videos
Hello, I'm pretty new to React so I will try to explain my issue the best I can.
I have a component <Equation /> nested in <Picker />
I am trying to click a button inside of <Picker /> and have useState() update content inside of <Equation />.
I have a state set with const [operator, setOperator] = React.useState("+") inside of the Picker component that works fine , <Equation operation={operator} /> up until I add setOperator() to the onClick in the button.
<button className="Picker" onClick={(setText("Addition"), setOperator("+"))} >
Once I add this to the element I get this error
Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
Here is is a link to the Components https://gist.github.com/tbednarz/20f166f1ad8161d24b02ae30bded0cd2
Problem is here updateState({...state, name: 'something'}) , you're updating state the before even it's rendering and that continues the updates the state, which will re-render, it goes on. Use useEffect to update the state.
useEffect(() => {
updateState({...state, name: 'something'});
}, [])
The issue is that you are updating the state on every render using updateState({...state, name: 'something'});, which then triggers a new render, etc etc.
If you want the state to contain multiple variables, you have two main options.
Use multiple useState hooks:
export default function App() {
const [dishes, setDishes] = useState(DISHES)
const [name, setName] = useState('something')
return <div></div>
}
Or, since you are using an object for your current state, you could just add more properties:
export default function App() {
const [state, updateState] = useState({
dishes: DISHES,
name: 'something'
});
return <div></div>
}
This second method will work, but React will not do deep comparison between object states, so it's generally more efficient to use the first method.
This is the offending code:
const [users, setUsers] = useState([]);
cognitoidentityserviceprovider.listUsers(params, (err, data) => {
if (err) {
console.log(err);
} else {
setUsers(data.Users);
console.log(data);
}
});I really see no reason as to why this will send the code into an infinite loop but it does for some reason. I tried calling it within useEffect, but passing an empty array or [users] to it does nothing at all, and no array sends it into a loop again.
Is there something I'm just misunderstanding about Hooks here?