Hi I have been stuck in a React Function useState
. I just want to learn hooks and useState, but I can not have any progress even struggling too much to find a solution. Here is my full react function:
import React, { useState } from 'react';
import './MainPart.css';
function MainPart(props) {
const [orderData_, setOrderData_] = useState(props.orderData);
let topicData_ = props.topicData;
let titleData_ = props.titleData;
let infoData_ = props.infoData;
return (
<div className='MainPart'>
<div className='mainWindow'>{getPics(orderData_)}</div>
<div className='information'>
<div className='moreNewsDivs'>
<div className='moreNewsDiv1'>
<h4>MORE NEWS</h4>
</div>
<div className='moreNewsDiv2'>
<button
className='previous-round'
onClick={setOrderData_(previous(orderData_))}
>
‹
</button>
<button href='/#' className='next-round'>
›
</button>
</div>
</div>
<hr />
<div className='topicDiv'>
<h5 className='topicData'>{topicData_}</h5>
<h5 className='titleData'>{titleData_}</h5>
<h6 className='infoData'>{infoData_}</h6>
</div>
</div>
</div>
);
}
function previous(orderData_) {
let newOrderData;
if (orderData_ === 3) {
newOrderData = 2;
console.log(newOrderData);
return newOrderData;
} else if (orderData_ === 1) {
newOrderData = 3;
console.log(newOrderData);
return newOrderData;
} else {
newOrderData = 1;
console.log(newOrderData);
return newOrderData;
}
}
function next(orderData_) {
let newOrderData;
if (orderData_ === 3) {
newOrderData = 1;
} else if (orderData_ === 2) {
newOrderData = 3;
} else {
newOrderData = 2;
}
return newOrderData;
}
const getPics = picOrder => {
if (picOrder === 1) {
return (
<img
src={require('../assets/desktopLarge/mainImage.png')}
className='MainImage'
alt=''
id='mainImage'
/>
);
} else if (picOrder === 2) {
return (
<img
src={require('../assets/desktopLarge/bridge.png')}
className='MainImage'
alt=''
id='mainImage'
/>
);
} else {
return (
<img
src={require('../assets/desktopLarge/forest.png')}
className='MainImage'
alt=''
id='mainImage'
/>
);
}
};
export default MainPart;
I am getting an error while using useState
. Even loading the page fresh and not pressed to anything my buttons onClick event listener activated and As I mentioned before at the topic My Error:
"Error: Too many re-renders. React limits the number of renders to prevent an infinite loop."
The problem can be found in your onClick
prop:
<button className="previous-round" onClick={setOrderData_(previous(orderData_))}>‹</button>
^
Everything between the curly braces gets evaluated immediately. This causes the setOrderData_
function to be called in every render loop.
By wrapping the function with an arrow function, the evaluated code will result in a function that can be called whenever the user clicks on the button.
<button className="previous-round" onClick={() => setOrderData_(previous(orderData_))}
>‹</button>
You can find more information about JSX and expressions in the official docs https://reactjs.org/docs/introducing-jsx.html#embedding-expressions-in-jsx
The reason for the infinite loop is because something (most likely setState
) in the event callback is triggering a re-render. This will call the event callback again and causes React to stop and throw the 'Too many re-renders.' error.
To better understand the reason why JSX works this way see the code below. JSX is actually being compiled to Javascript and every prop will be passed to a function in an Object. With this knowledge, you will see that handleEvent()
is being called immediately in the last example.
// Simple example
// JSX: <button>click me</button>
// JS: createElement('button', { children: 'click me' })
createElement("button", { children: "click me" });
// Correct event callback
// JSX: <button onClick={handleClick}>click me</button>
// JS: createElement('button', { onClick: handleClick, children: 'click me' })
createElement("button", { onClick: handleClick, children: "click me" });
// Wrong event callback
// JSX: <button onClick={handleClick()}>click me</button>
// JS: createElement('button', { onClick: handleClick(), children: 'click me' })
createElement("button", { onClick: handleClick(), children: "click me" });