score:382
that because you calling toggle inside the render method which will cause to re-render and toggle will call again and re-rendering again and so on
this line at your code
{<td><span onClick={this.toggle()}>Details</span></td>}
you need to make onClick
refer to this.toggle
not calling it
to fix the issue do this
{<td><span onClick={this.toggle}>Details</span></td>}
score:0
Many good answer but all missing some example considering hooks in react/ React native
As wrote in an answer above is that the callback should not be "called" inside the child Component but only referenced.
What this means? Let's consider a Parent Component that take 2 Children Components that change rgb color for change color on press:
import React, { useState } from "react"
import {View, Text, StyleSheet } from "react-native"
import ColorCounter from "../components/ColorCounter"
const SquareScreen = () =>{
const [red, setRed] = useState(0)
const [blue, setBlue] = useState(0)
const [green, setGreen] = useState(0)
return (
<View>
<ColorCounter
onIncrease={() => setRed(red + 15)}
onDecrease={() => setRed(red - 15)}
color="Red"
/>
<ColorCounter
onIncrease={() => setBlue(blue + 15)}
onDecrease={() => setBlue(blue - 15)}
color="Blue"
/>
<ColorCounter
onIncrease={() => setGreen(green + 15)}
onDecrease={() => setGreen(green - 15)}
color="Green"
/>
<View
style={{
height:150,
width:150,
backgroundColor:`rgb(${red},${blue},${green})`
}}
/>
</View>
)
}
const styles = StyleSheet.create({})
export default SquareScreen
This is the Child Button Component:
import React, { useState } from "react"
import {View, Text, StyleSheet, Button } from "react-native"
const ColorCounter = ({color, onIncrease, onDecrease}) =>{
return (
<View>
<Text>{color}</Text>
<Button onPress={onIncrease} title={`Increase ${color}`} /> --> here if you use onPress={onIncrease()} this would cause a call of setColor(either setRed,SetBlue or setGreen) that call again onIncrease and so on in a loop)
<Button onPress={onDecrease} title={`Decrease ${color}`} />
</View>
)
}
export default ColorCounter
score:1
onClick you should call function, thats called your function toggle.
onClick={() => this.toggle()}
score:1
Recently I got this error:
Error: Minified React error #185; visit https://reactjs.org/docs/error-decoder.html?invariant=185 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
The full text of the error you just encountered is:
Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside
componentWillUpdate
orcomponentDidUpdate
. React limits the number of nested updates to prevent infinite loops.
Ok. Here is my case, I use react function component + react hooks. Let's see the incorrect sample code first:
import { useEffect, useState } from "react";
const service = {
makeInfo(goods) {
if (!goods) return { channel: "" };
return { channel: goods.channel };
},
getGoods() {
return new Promise((resolve) => {
setTimeout(() => {
resolve({
channel: "so",
id: 1,
banners: [{ payway: "visa" }, { payway: "applepay" }]
});
}, 1000);
});
},
makeBanners(info, goods) {
if (!goods) return [];
return goods.banners.map((v) => {
return { ...v, payway: v.payway.toUpperCase() };
});
}
};
export default function App() {
const [goods, setGoods] = useState();
const [banners, setBanners] = useState([]);
useEffect(() => {
service.getGoods().then((res) => {
setGoods(res);
});
}, []);
const info = service.makeInfo(goods);
useEffect(() => {
console.log("[useEffect] goods: ", goods);
if (!goods) return;
setBanners(service.makeBanners({}, goods));
}, [info, goods]);
return <div>banner count: {banners.length}</div>;
}
service
- process API call, and has some methods for converting DTO data view model. It has nothing to do with React. Maybe you have a service like this in your project.
My logic is that the banners
view model constructs from the goods
data returned from the API.
useEffect({...}, [info, goods])
has two dependencies: info
and goods
.
When info
and goods
change, useEffect
hook will re-execute, set banners view model, it looks good, right?
No! It will cause a memory leak. The useEffect
hook will execute infinitely. Why?
Because when setBanner()
executed, the component will re-render, the const info = service.makeInfo(goods);
statement will execute again, returns a new info
object, this will lead to the change of the useEffect
's deps, causing useEffect
to execute again, forming a dead cycle.
Solutions: use useMemo
returns a memorized value. Use this memorized value as the dependency of the useEffect
hook.
// ...
const info = useMemo(() => {
return service.makeInfo(goods);
}, [goods]);
useEffect(() => {
console.log("[useEffect] goods: ", goods);
if (!goods) return;
setBanners(service.makeBanners({}, goods));
}, [info, goods]);
//...
score:4
ReactJS: Maximum update depth exceeded error
inputDigit(digit){
this.setState({
displayValue: String(digit)
})
<button type="button"onClick={this.inputDigit(0)}>
why that?
<button type="button"onClick={() => this.inputDigit(1)}>1</button>
The function onDigit sets the state, which causes a rerender, which causes onDigit to fire because that’s the value you’re setting as onClick which causes the state to be set which causes a rerender, which causes onDigit to fire because that’s the value you’re… Etc
score:6
In this case , this code
{<td><span onClick={this.toggle()}>Details</span></td>}
causes toggle function to call immediately and re render it again and again thus making infinite calls.
so passing only the reference to that toggle method will solve the problem.
so ,
{<td><span onClick={this.toggle}>Details</span></td>}
will be the solution code.
If you want to use the () , you should use an arrow function like this
{<td><span onClick={()=> this.toggle()}>Details</span></td>}
In case you want to pass parameters you should choose the last option and you can pass parameters like this
{<td><span onClick={(arg)=>this.toggle(arg)}>Details</span></td>}
In the last case it doesn't call immediately and don't cause the re render of the function, hence avoiding infinite calls.
score:7
1.If we want to pass argument in the call then we need to call the method like below
As we are using arrow functions no need to bind the method in constructor
.
onClick={() => this.save(id)}
when we bind the method in constructor like this
this.save= this.save.bind(this);
then we need to call the method without passing any argument like below
onClick={this.save}
and we try to pass argument while calling the function as shown below then error comes like maximum depth exceeded.
onClick={this.save(id)}
score:9
if you don't need to pass arguments to function, just remove () from function like below:
<td><span onClick={this.toggle}>Details</span></td>
but if you want to pass arguments, you should do like below:
<td><span onClick={(e) => this.toggle(e,arg1,arg2)}>Details</span></td>
score:14
I know this has plenty of answers but since most of them are old (well, older), none is mentioning approach I grow very fond of really quick. In short:
Use functional components and hooks.
In longer:
Try to use as much functional components instead class ones especially for rendering, AND try to keep them as pure as possible (yes, data is dirty by default I know).
Two bluntly obvious benefits of functional components (there are more):
- Pureness or near pureness makes debugging so much easier
- Functional components remove the need for constructor boiler code
Quick proof for 2nd point - Isn't this absolutely disgusting?
constructor(props) {
super(props);
this.toggle= this.toggle.bind(this);
this.state = {
details: false
}
}
If you are using functional components for more then rendering you are gonna need the second part of great duo - hooks. Why are they better then lifecycle methods, what else can they do and much more would take me a lot of space to cover so I recommend you to listen to the man himself: Dan preaching the hooks
In this case you need only two hooks:
A callback hook conveniently named useCallback
. This way you are preventing the binding the function over and over when you re-render.
A state hook, called useState
, for keeping the state despite entire component being function and executing in its entirety (yes, this is possible due to magic of hooks). Within that hook you will store the value of toggle.
If you read to this part you probably wanna see all I have talked about in action and applied to original problem. Here you go: Demo
For those of you that want only to glance the component and WTF is this about, here you are:
const Item = () => {
// HOOKZ
const [isVisible, setIsVisible] = React.useState('hidden');
const toggle = React.useCallback(() => {
setIsVisible(isVisible === 'visible' ? 'hidden': 'visible');
}, [isVisible, setIsVisible]);
// RENDER
return (
<React.Fragment>
<div style={{visibility: isVisible}}>
PLACEHOLDER MORE INFO
</div>
<button onClick={toggle}>Details</button>
</React.Fragment>
)
};
PS: I wrote this in case many people land here with similar problem. Hopefully, they will like what I have shown here, at least well enough to google it a bit more. This is NOT me saying other answers are wrong, this is me saying that since the time they have been written, there is another way (IMHO, a better one) of dealing with this.
score:40
Forget about the react first:
This is not related to react and let us understand the basic concepts of Java Script. For Example you have written following function in java script (name is A).
function a() {
};
Q.1) How to call the function that we have defined?
Ans: a();
Q.2) How to pass reference of function so that we can call it latter?
Ans: let fun = a;
Now coming to your question, you have used paranthesis with function name, mean that function will be called when following statement will be render.
<td><span onClick={this.toggle()}>Details</span></td>
Then How to correct it?
Simple!! Just remove parenthesis. By this way you have given the reference of that function to onClick event. It will call back your function only when your component is clicked.
<td><span onClick={this.toggle}>Details</span></td>
One suggestion releated to react:
Avoid using inline function as suggested by someone in answers, it may cause performance issue.
Avoid following code, It will create instance of same function again and again whenever function will be called (lamda statement creates new instance every time).
Note: and no need to pass event (e) explicitly to the function. you can access it with in the function without passing it.
{<td><span onClick={(e) => this.toggle(e)}>Details</span></td>}
https://cdb.reacttraining.com/react-inline-functions-and-performance-bdff784f5578
score:42
You should pass the event object when calling the function :
{<td><span onClick={(e) => this.toggle(e)}>Details</span></td>}
If you don't need to handle onClick event you can also type :
{<td><span onClick={(e) => this.toggle()}>Details</span></td>}
Now you can also add your parameters within the function.
Source: stackoverflow.com
Related Query
- ReactJS - Maximum update depth exceeded error
- ReactJS - error on maximum update depth exceeded despite conditional check
- ReactJS: Maximum update depth exceeded error
- React Maximum update depth exceeded error caused by useEffect only in test
- React App Login Error : Maximum update depth exceeded
- Maximum update depth exceeded in React error
- RESOLVE : react error : Maximum update depth exceeded
- Error with React Stripe split card elements: Maximum update depth exceeded
- ComponentDidUpdate - Maximum update depth exceeded - Error
- Maximum depth update exceeded error when navigating to routes react-router v6
- Why I'm getting maximum update depth exceeded error when setting data to context (React)
- Maximum update depth exceeded ReactJs componentDidMount
- ReactJS: using localStorage to save data breaks with error Maximum update depth exceeded
- React error in console - Maximum update depth exceeded when input length is more than 5
- Trying to pass state value from child to parent, getting Maximum Update Depth Exceeded error
- I am getting this error like index.js:1 Warning: Maximum update depth exceeded
- Maximum update depth exceeded error in react app
- React Typescript with hooks : Maximum update depth exceeded error
- React error --> Error: Maximum update depth exceeded
- I get an Error from React: Maximum update depth exceeded
- I receive this error while trying to implement JWT Authentication, Error: Maximum update depth exceeded
- React: how do I get rid of this Maximum update depth exceeded error
- ReactJs throwing maximum update depth error
- React does not recognize the `totalPrice and totalQuantity` prop on a DOM element and Maximum update depth exceeded Error
- ReactJS Error: Maximum update depth exceeded
- React getting Maximum update depth exceeded error
- React hooks Maximum update depth exceeded error
- React state update from Redux causing Maximum update depth exceeded error
- ReactNative: Maximum update depth exceeded error
- I am getting the following error while creating a signin page using react : Error: Maximum update depth exceeded
More Query from same tag
- How do I configure my .htaccess file for React App in Subdirectory?
- Disqus comments throws error in a Gatsby site
- Why is my useHistory undefined even when it is within the Router?
- React routing on click event is not working
- How do you manage component state in Next.js
- Hook with props
- React Conditional state update not working
- How to properly destructure assignment with dynamic key? (react/destructuring-assignment)
- Firebase sign in with google for web not redirecting
- unable to only select a single material ui checkbox
- How to match string with multiple variables?
- How to update a state variable correctly using onClick in functional component
- × TypeError: Cannot read property 'location' of undefined
- React custom hooks and useMemo hooks
- Redux Form wrapper around Field components
- Using if else in stateless functional component results in error when returning null
- React TypeScript: window onClick type
- Custom CSS Support for NextJS
- How to render Material Ui buttons next to image list?
- Xcode: ld: 275 duplicate symbols for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
- Textarea placeholder isn't shown in IE 11 being rendered using React
- React Enzyme Type Error:Cannot read property 'propTypes' of undefined
- Modal visible in HTML but on visible on app
- Deployd and universal/isomorphic React app
- How do you export a prop name and the type instead of defining it everywhere?
- How to wrap the initialisation of an array in its own useMemo() Hook?
- create-react-app integrate with storybook 6.1.6 and build has error
- Cannot find 'LeftSegment' & Cannot find 'infer' error in react-router folder in node_modules
- How to make a second API call based on the first response?
- Should I include setState in useCallback's array of dependencies?