staskjs staskjs - 2 months ago 28
React JSX Question

"Cannot update during existing date transition" using react-navigation with redux in react-native

I have just started learning react-native and redux. I am trying to implement authentication scenario. I am using

react-navigation
.

import { authenticate } from './../actions';

const Component = (props) => {
const { dispatch, user } = props;

// user comes from state (using mapStateToProps)

let phone = '';
let password = '';

if (user.errors != null) {
alert(user.errors);
}

if (user.authenticated) {
dispatch(NavigationActions.navigate({ routeName: 'LoggedIn' }));
}

async function onLogin() {
dispatch(authenticate(phone, password));
}

return (
<View>
<TextInput
style={{height: 40, width: '100%', borderColor: 'gray', borderWidth: 1, marginTop: 10}}
placeholder="(xxx) xxx-xx-xx"
keyboardType={'phone-pad'}
onChangeText={(value) => phone = value}
value={phone}
/>
<TextInput
style={{height: 40, width: '100%', borderColor: 'gray', borderWidth: 1, marginTop: 10}}
placeholder="Пароль"
onChangeText={(value) => password = value}
value={password}
/>
<Button
onPress={onLogin}
title="Continue"
/>
</View>
);
}


Here is authenticate action

export function authenticate(phone, password) {
return async dispatch => {
dispatch(authenticating());
let response;
try {
response = await Api.authenticate(phone, password);
}
catch (e) {
dispatch(authenticateFailure(e.error));
return;
}
dispatch(authenticateSuccess(response.token, response.payload));
};
};


So basically when
authenticate
action is dispatched and user is authenticated successfully, I want to redirect user to next screen (
LoggedIn
). But after redirection I get this error:

Warning: Cannot update during an existing state transition (such as within render or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to componentWillMount.


I guess problem is that previous component is interrupted being rendered when it is redirecting to next component (LoggedIn), because every dispatch triggers rerender.

How do I navigate to another screen after action is dispatched? Can I somehow dispatch an action without triggering rerender?

Answer Source

try move all of this to

componentWillReceiveProps(nextProps) {
   // check props you want to use as execution trigger 
 }

#

const { dispatch, user } = props;

// user comes from state (using mapStateToProps)

let phone = '';
let password = '';

if (user.errors != null) {
  alert(user.errors);
}

if (user.authenticated) {
    dispatch(NavigationActions.navigate({ routeName: 'LoggedIn' }));
}

async function onLogin() {    
  dispatch(authenticate(phone, password));
}

you might need to adapt some const you use inside render method