React - 不变违规:超出最大更新深度
React - Invariant Violation: Maximum update depth exceeded
我有从另一个class设置我的状态的功能,但我得到了以下错误
Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
我的代码如下
constructor(props) {
super(props)
this.state = { loading: true, showAction: false }
setTimeout(() => {
StatusBar.setBackgroundColor(primary)
}, 100)
}
async componentWillMount() {
await Font.loadAsync({
Roboto: require("native-base/Fonts/Roboto.ttf"),
Roboto_medium: require("native-base/Fonts/Roboto_medium.ttf"),
Ionicons: require("@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/Ionicons.ttf"),
});
this.setState({ loading: false });
}
setShowAction = (isShowAction) => {
console.log(isShowAction)
this.setState({
showAction: isShowAction
})
}
...
<ChatListScreen onAction={(isShowAction) => this.setShowAction(isShowAction)}/>
...
const ChatListScreen = ({ onAction }) => {
return (
<ChatList onAction={(isShowAction) => onAction(isShowAction)}/>
)
}
...
const ChatList = ({ onAction }) => {
const [selectMode, setSelectMode] = useState(false)
const chatListDummy = []
const [selectedItem, setSelectedItem] = useState([])
{selectMode ? onAction(true) : onAction(false)}
return (
<FlatList
data= {chatListDummy}
keyExtractor= {chat => chat.id}
renderItem= {({item}) => {
}}/>
)
}
export default ChatList
有人能帮忙吗?
查看我的解决方案
const ChatListScreen = ({ onAction }) => {
return (
<ChatList onAction={(isShowAction) => onAction(isShowAction)}/>
)
}
const ChatList = ({ onAction }) => {
const [selectMode, setSelectMode] = useState(false)
const [selectedItem, setSelectedItem] = useState([])
//i dont know where are you using this actally you most use this in a lifesycle or a function
// {selectMode ? onAction(true) : onAction(false)}
function onClick(){
selectMode ? onAction(true) : onAction(false)
}
//or a lifecycle
useEffect(()=>{
selectMode ? onAction(true) : onAction(false)
},[])
return (<div onClick ={onClick} >{"your content"}</div>)
尽量避免将匿名函数作为 props 传递给 React 组件。这是因为 React 将始终重新渲染您的组件,因为它无法将其状态与前一个组件进行比较,这也是一个匿名函数。
话虽如此,但在某些情况下传递匿名函数是不可避免的。在那种情况下,永远不要在匿名函数中更新你的状态。这是您方案中的主要问题,这是发生了什么:
- 您将匿名函数作为 prop 传递给您的组件。
- 当组件接收到这个函数时,它无法将它与之前的状态进行比较,因此重新渲染你的组件。
- 在你的匿名函数中,你正在更新你的状态。更新你的状态会强制 React 再次重新渲染组件。
this.setState({
showAction: isShowAction
}) //this portion is mainly responsible for the error
- 因此这个循环一直持续到阈值,直到 React 抛出错误
Maximum update depth exceeded.
我有从另一个class设置我的状态的功能,但我得到了以下错误
Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
我的代码如下
constructor(props) {
super(props)
this.state = { loading: true, showAction: false }
setTimeout(() => {
StatusBar.setBackgroundColor(primary)
}, 100)
}
async componentWillMount() {
await Font.loadAsync({
Roboto: require("native-base/Fonts/Roboto.ttf"),
Roboto_medium: require("native-base/Fonts/Roboto_medium.ttf"),
Ionicons: require("@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/Ionicons.ttf"),
});
this.setState({ loading: false });
}
setShowAction = (isShowAction) => {
console.log(isShowAction)
this.setState({
showAction: isShowAction
})
}
...
<ChatListScreen onAction={(isShowAction) => this.setShowAction(isShowAction)}/>
...
const ChatListScreen = ({ onAction }) => {
return (
<ChatList onAction={(isShowAction) => onAction(isShowAction)}/>
)
}
...
const ChatList = ({ onAction }) => {
const [selectMode, setSelectMode] = useState(false)
const chatListDummy = []
const [selectedItem, setSelectedItem] = useState([])
{selectMode ? onAction(true) : onAction(false)}
return (
<FlatList
data= {chatListDummy}
keyExtractor= {chat => chat.id}
renderItem= {({item}) => {
}}/>
)
}
export default ChatList
有人能帮忙吗?
查看我的解决方案
const ChatListScreen = ({ onAction }) => {
return (
<ChatList onAction={(isShowAction) => onAction(isShowAction)}/>
)
}
const ChatList = ({ onAction }) => {
const [selectMode, setSelectMode] = useState(false)
const [selectedItem, setSelectedItem] = useState([])
//i dont know where are you using this actally you most use this in a lifesycle or a function
// {selectMode ? onAction(true) : onAction(false)}
function onClick(){
selectMode ? onAction(true) : onAction(false)
}
//or a lifecycle
useEffect(()=>{
selectMode ? onAction(true) : onAction(false)
},[])
return (<div onClick ={onClick} >{"your content"}</div>)
尽量避免将匿名函数作为 props 传递给 React 组件。这是因为 React 将始终重新渲染您的组件,因为它无法将其状态与前一个组件进行比较,这也是一个匿名函数。
话虽如此,但在某些情况下传递匿名函数是不可避免的。在那种情况下,永远不要在匿名函数中更新你的状态。这是您方案中的主要问题,这是发生了什么:
- 您将匿名函数作为 prop 传递给您的组件。
- 当组件接收到这个函数时,它无法将它与之前的状态进行比较,因此重新渲染你的组件。
- 在你的匿名函数中,你正在更新你的状态。更新你的状态会强制 React 再次重新渲染组件。
this.setState({
showAction: isShowAction
}) //this portion is mainly responsible for the error
- 因此这个循环一直持续到阈值,直到 React 抛出错误
Maximum update depth exceeded.