Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

433
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda