4

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?

Hanif Nr
  • 432
  • 1
  • 5
  • 15
  • could you please show us `ChatListScreen` codes ? – MBehtemam Apr 28 '20 at 07:47
  • You probably need to use arrow function in your code. When you are not binding your methods properly react begins to call them continuously..which leads to the maximum-update-depth-exceeded errors – Imjaad Apr 28 '20 at 08:04
  • {selectMode ? onAction(true) : onAction(false)} hi where are you usin this? in render or a function or lifecycle? – morteza moradi Apr 28 '20 at 08:14
  • how about putting `{selectMode ? onAction(true) : onAction(false)} ` into `useEffect` – MBehtemam Apr 28 '20 at 08:20

2 Answers2

3

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>)
morteza moradi
  • 145
  • 2
  • 9
1

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.
Anus Kaleem
  • 544
  • 4
  • 16
  • Alright, how it should be then? because in this case i want to set state from its child component – Hanif Nr Apr 28 '20 at 09:46
  • 1
    Manage your app state in a centralised manner using any of the state management tool, then map your state to props and use them as props in your component. – Anus Kaleem Apr 28 '20 at 09:51