Hanif Nr
Hanif Nr

Reputation: 462

React - Invariant Violation: Maximum update depth exceeded

I have function for set my state from another class, but i got this following error

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.

And here's my code looks like

  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

Can anyone help?

Upvotes: 4

Views: 593

Answers (2)

morteza moradi
morteza moradi

Reputation: 143

see my solution

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>)

Upvotes: 3

Anus Kaleem
Anus Kaleem

Reputation: 564

Try to avoid passing anonymous functions as props to React components. This is because React will always re render your component as it will fail to compare its state to the previous one, which too is an anonymous function.

Having said that, there will be some cases in which passing anonymous functions would be unavoidable. In that case, never update your state inside the anonymous function. This is the main problem in your scenario, here is whats happening:

  1. You pass anonymous function as a prop to your component.
  2. When component receives this function, it is failed to compare it with the previous state and hence re renders your component.
  3. Inside your anonymous function, you are updating your state. Updating your state would force React to re render component again.
    this.setState({
      showAction: isShowAction
    }) //this portion is mainly responsible for the error
  1. Hence this cycle continues up till a threshold till React throws an error Maximum update depth exceeded.

Upvotes: 1

Related Questions