Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

431
Views
React-Native: cannot update a component while rendering a different component

I've got this simple component Login:

function Login() {
  const [isFormValidState, setIsFormValidState] = React.useState(false);
  const [credentialState, setCredentialState] = React.useState();

  function getFormErrors(errors: any, dirty: boolean) {
    setIsFormValidState(!Object.keys(errors).length && dirty);
  }

  function getFormValues(values: any) {
    setCredentialState(values);
  }

  function doAction() {
    //credentialState rest call...
  }

  return (
    <View>
      <Text>Login</Text>
      <UserCredentialForm getFormValues={getFormValues} getFormErrors={getFormErrors}/>
      <Button title='Entra' disabled={!isFormValidState} onPress={doAction}/>
    </View>
  );
}

Which calls UserCredentialForm:

export default function UserCredentialForm({ getFormValues, getFormErrors }) {
[...]
  return (
    <Formik innerRef={formRef} validationSchema={formSchema} initialValues={state.form} onSubmit={() => { }}>
      {({ handleChange, values, touched, errors, dirty }) => {
        getFormValues(values);
        getFormErrors(errors, dirty);
        return <React.Fragment>
          // <TextInput/>....              
        </React.Fragment>
      }}
    </Formik>
  );

[...]
}

While navigating in my app I've got this error:

react native cannot update a component Login while rendering a different component Formik.

Then it points me to the error in the setCredentialState inside getFormValues handler in Login component. I've resolved this using a ref instead of a state, but the problem itself is unsolved to me.

What if I need to update my parent component view after a child event?

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

I think you got an unlimited loop of rendering,

you setState by getFormValues and the Login component re-render make UserCredentialForm re-render too, so it call getFormValues again and again

You can call getFormValues(values) in a useEffect hook after values of formik update

over 4 years ago · Santiago Trujillo Report

0

Simple example can be like

UserCredentialForm:

 // Formik x React Native example
 import React from 'react';
 import { Button, TextInput, View } from 'react-native';
 import { Formik } from 'formik';
 
 export const MyReactNativeForm = ({onSubmit}) => (
   <Formik
     initialValues={{ email: '' }}
     onSubmit={values => onSubmit(values)}
   >
     {({ handleChange, handleBlur, handleSubmit, values }) => (
       <View>
         <TextInput
           onChangeText={handleChange('email')}
           onBlur={handleBlur('email')}
           value={values.email}
         />
         <Button onPress={handleSubmit} title="Submit" />
       </View>
     )}
   </Formik>
 );

Usage like

function Login() {

  function doAction(values) {
    console.log(values);
    //credentialState rest call...
  }

  return (
    <View>
      ....
      <UserCredentialForm onSubmit={doAction} />
      ....
    </View>
  );
}
over 4 years ago · Santiago Trujillo Report

0

The reason for that error is because you call setState inside render(). The call getFormValues(values), which set the state of credentialState is called inside the render.

When the state is set, the Login component get rerendered, thus recreating a new function of getFormValues. As this is used as the prop of UserCredentialForm, it also causes that component to rerender, which causes the render prop inside Formik to calls again, which calls getFormValues causing the state change, causing an infinite loop.

One solution you can try is to add useCallback to the two functions, which prevent them to have new identities after the state changes and consequently change the props, thus creating infinite rerender.

function Login() {
  const [isFormValidState, setIsFormValidState] = React.useState(false);
  const [credentialState, setCredentialState] = React.useState();

  const getFormErrors = useCallback(function getFormErrors(errors: any, dirty: boolean) {
    setIsFormValidState(!Object.keys(errors).length && dirty);
  }, []);

  const getFormValues = useCallback(function getFormValues(values: any) {
    setCredentialState(values);
  }, []);

  function doAction() {
    //credentialState rest call...
  }

  return (
    <View>
      <Text>Login</Text>
      <UserCredentialForm getFormValues={getFormValues} getFormErrors={getFormErrors}/>
      <Button title='Entra' disabled={!isFormValidState} onPress={doAction}/>
    </View>
  );
}

However, there is still an issue and that is the identity of values may not be stable and by setting it to state, it will keep causing rerender. What you want to do is to tell UserCredentialForm not to rerender even when that state changes, and since the state is not used as a prop in UserCredentialForm, you can do that with React.memo.


export default React.memo(function UserCredentialForm({ getFormValues, getFormErrors }) {
[...]
  return (
    <Formik innerRef={formRef} validationSchema={formSchema} initialValues={state.form} onSubmit={() => { }}>
      {({ handleChange, values, touched, errors, dirty }) => {
        getFormValues(values);
        getFormErrors(errors, dirty);
        return <React.Fragment>
          // <TextInput/>....              
        </React.Fragment>
      }}
    </Formik>
  );

[...]
})
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!