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."
To get rid of your infinite loop, simply use an empty dependency array like so: const [count, setCount] = useState(0); //only update the value of 'count' when component is first mounted useEffect(() => { setCount((count) => count + 1); }, []); This will tell React to run useEffect on the first render.
1. Memoization using useMemo() and UseCallback() Hooks. Memoization enables your code to re-render components only if there's a change in the props. With this technique, developers can avoid unnecessary renderings and reduce the computational load in applications.
You can see in the console tab, that the render lifecycle got triggered more than once on both the app and greeting component. This is because the React app component got re-rendered after the state values were modified, and it also re-rendered its child components.
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" });
Just replace your button with the one below
<button className="previous-round" onClick={() => setOrderData_(previous(orderData_))}>‹</button>
This happens because onClick function if used without an anonymous functions gets called immediately and that setOrderData again re renders it causing an infinite loop. So its better to use anonymous functions.
Hope it helps. feel free for doubts.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With