我试图在ReactJS中切换组件的状态,但我得到一个错误说明:
超过最大更新深度。当组件在componentWillUpdate或componentDidUpdate中反复调用setState时,就会发生这种情况。React限制了嵌套更新的数量,以防止无限循环。
我在我的代码中没有看到无限循环,有人能帮我吗?
ReactJS组件代码:
import React, { Component } from 'react';
import styled from 'styled-components';
class Item extends React.Component {
constructor(props) {
super(props);
this.toggle= this.toggle.bind(this);
this.state = {
details: false
}
}
toggle(){
const currentState = this.state.details;
this.setState({ details: !currentState });
}
render() {
return (
<tr className="Item">
<td>{this.props.config.server}</td>
<td>{this.props.config.verbose}</td>
<td>{this.props.config.type}</td>
<td className={this.state.details ? "visible" : "hidden"}>PLACEHOLDER MORE INFO</td>
{<td><span onClick={this.toggle()}>Details</span></td>}
</tr>
)}
}
export default Item;
很多好答案,但都遗漏了一些例子,考虑到react/ react native中的钩子
正如上面的回答中所写的,回调不应该在子组件内部被“调用”,而只能被引用。
这意味着什么?
让我们考虑一个父组件,它有2个改变rgb颜色的子组件:
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
这是子按钮组件:
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
在本例中,就是这段代码
{<td><span onClick={this.toggle()}>Details</span></td>}
导致切换函数立即调用,并重新呈现它一次又一次,从而进行无限的调用。
因此,只传递对toggle方法的引用就可以解决问题。
所以,
{<td><span onClick={this.toggle}>Details</span></td>}
将是解决方案代码。
如果你想使用(),你应该使用一个像这样的箭头函数
{<td><span onClick={()=> this.toggle()}>Details</span></td>}
如果你想传递参数,你应该选择最后一个选项,你可以这样传递参数
{<td><span onClick={(arg)=>this.toggle(arg)}>Details</span></td>}
在最后一种情况下,它不会立即调用,也不会导致函数的重新呈现,因此避免了无限调用。
1.如果我们想在调用中传递参数,那么我们需要像下面这样调用方法
因为我们使用的是箭头函数,所以不需要在构造函数中绑定方法。
onClick={() => this.save(id)}
当我们像这样在构造函数中绑定方法时
this.save= this.save.bind(this);
然后,我们需要调用该方法而不传递任何参数,如下所示
onClick={this.save}
我们尝试在调用函数时传递参数
如下所示,然后误差就像最大深度超出。
onClick={this.save(id)}