Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot update during an existing state transition #2063

Closed
necsoft opened this issue Jul 18, 2017 · 16 comments
Closed

Cannot update during an existing state transition #2063

necsoft opened this issue Jul 18, 2017 · 16 comments

Comments

@necsoft
Copy link

necsoft commented Jul 18, 2017

I'm sorry for this newbie question but I can't understand what's happening.

This is my code:

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  Button,
  View
} from 'react-native';

import {
  Scene,
  Router,
  Actions
} from 'react-native-router-flux';

class App extends Component {
  render() {
    return (
      <Router>
        <Scene key="root">
          <Scene key="home" component={Home} title="Home"/> 
          <Scene key="details" component={Details} title="Details"/>
        </Scene>
      </Router>
    );
  }
}

class Home extends Component {
  render() {
    return (
      <View style={styles.container_home}>
        <Text style={styles.welcome}>
          Home Screen
        </Text>
        <Button
          onPress={()=>Actions.details()}
          title="Details"
          color="#ffffff"
        />
      </View>
    );
  }
}

class Details extends Component {
  render() {
    return (
      <View style={styles.container_details}>
        <Text style={styles.welcome}>
          Details Screen
        </Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container_home: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#333333',
  },
  container_details: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'gray',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
    color:'#FFC300'
  },
});

AppRegistry.registerComponent('react_native_router_flux', () => App);

And I am getting this message when I save with Hot Reloading:

screen shot 2017-07-18 at 3 43 32 pm

Thanks in advance!

@aksonov
Copy link
Owner

aksonov commented Jul 18, 2017

It could be React Navigation issue. Could you please rework your example with ReactNavigation only and check.

@necsoft
Copy link
Author

necsoft commented Jul 18, 2017

I've tried with this similar code and it doesn't happen:

import React, { Component } from 'react';
import {
	AppRegistry,
	StyleSheet,
	Text,
	View,
	Button
} from 'react-native';

import { StackNavigator } from 'react-navigation';

class HomeScreen extends Component {
	
	static navigationOptions = {
		title: 'Home',
	};
	
	render() {
		const { navigate } = this.props.navigation;
		return (
			<View style={styles.container_home}>
			<Text style={styles.welcome}>
			Home Screen
			</Text>
			<Button
			onPress={() => navigate('Details')}
			title="Details"
			color="#ffffff"
			/>
			</View>
		);
	}
}

class DetailsScreen extends Component {
	
	static navigationOptions = {
		title: 'Details',
	};
	
	render() {
		return (
			<View style={styles.container_details}>
			<Text style={styles.welcome}>
			Details Screen
			</Text>
			</View>
		);
	}
}

const styles = StyleSheet.create({
	container_home: {
		flex: 1,
		justifyContent: 'center',
		alignItems: 'center',
		backgroundColor: '#333333',
	},
	container_details: {
		flex: 1,
		justifyContent: 'center',
		alignItems: 'center',
		backgroundColor: 'gray',
	},
	welcome: {
		fontSize: 20,
		textAlign: 'center',
		margin: 10,
		color:'#FFC300'
	},
});

const SimpleApp = StackNavigator({
	Home: { screen: HomeScreen },
	Details: { screen: DetailsScreen },
});

AppRegistry.registerComponent('react_navigation_test', () => SimpleApp);

@UlfR
Copy link

UlfR commented Jul 19, 2017

In case of me it this warning have next stacktrace:

reactConsoleErrorHandler ExceptionsManager.js:71
console.error YellowBox.js:67
printWarning warning.js:36
warning warning.js:60
getInternalInstanceReadyForUpdate ReactNativeStack-dev.js:1535
enqueueForceUpdate ReactNativeStack-dev.js:1552
ReactComponent.forceUpdate react.development.js:185
(anonymous) native.js:621
Reaction.runReaction mobx.js:2935
runReactionsHelper mobx.js:3062
reactionScheduler mobx.js:3040
(anonymous) mobx.js:3069
batchedUpdates ReactNativeStack-dev.js:2106
batchedUpdates$1 ReactNativeStack-dev.js:1465
reactionScheduler mobx.js:3069
runReactions mobx.js:3045
endBatch mobx.js:2602
endAction mobx.js:903
executeAction mobx.js:870
res mobx.js:858
NavigationStore.dispatch navigationStore.js:134
set navigationStore.js:76
Router Router.js:279
StatelessComponent.render ReactNativeStack-dev.js:1610
(anonymous) ReactNativeStack-dev.js:1881
measureLifeCyclePerf ReactNativeStack-dev.js:1625
_renderValidatedComponentWithoutOwnerOrContext ReactNativeStack-dev.js:1880
_renderValidatedComponent ReactNativeStack-dev.js:1890
_updateRenderedComponent ReactNativeStack-dev.js:1854
_performComponentUpdate ReactNativeStack-dev.js:1838
updateComponent ReactNativeStack-dev.js:1819
receiveComponent ReactNativeStack-dev.js:1784
receiveComponent ReactNativeStack-dev.js:1349
updateChildren ReactNativeStack-dev.js:2677
_reconcilerUpdateChildren ReactNativeStack-dev.js:2817
_updateChildren ReactNativeStack-dev.js:2852
updateChildren ReactNativeStack-dev.js:2849
receiveComponent ReactNativeStack-dev.js:2915
receiveComponent ReactNativeStack-dev.js:1349
_updateRenderedComponentWithNextElement ReactNativeStack-dev.js:1859
_updateRenderedComponent ReactNativeStack-dev.js:1855
_performComponentUpdate ReactNativeStack-dev.js:1838
updateComponent ReactNativeStack-dev.js:1819
receiveComponent ReactNativeStack-dev.js:1784
receiveComponent ReactNativeStack-dev.js:1349
updateChildren ReactNativeStack-dev.js:2677
_reconcilerUpdateChildren ReactNativeStack-dev.js:2817
_updateChildren ReactNativeStack-dev.js:2852
updateChildren ReactNativeStack-dev.js:2849
receiveComponent ReactNativeStack-dev.js:2915
receiveComponent ReactNativeStack-dev.js:1349
_updateRenderedComponentWithNextElement ReactNativeStack-dev.js:1859
_updateRenderedComponent ReactNativeStack-dev.js:1855
_performComponentUpdate ReactNativeStack-dev.js:1838
updateComponent ReactNativeStack-dev.js:1819
receiveComponent ReactNativeStack-dev.js:1784
receiveComponent ReactNativeStack-dev.js:1349
_updateRenderedComponentWithNextElement ReactNativeStack-dev.js:1859
_updateRenderedComponent ReactNativeStack-dev.js:1855
_performComponentUpdate ReactNativeStack-dev.js:1838
updateComponent ReactNativeStack-dev.js:1819
receiveComponent ReactNativeStack-dev.js:1784
receiveComponent ReactNativeStack-dev.js:1349
_updateRenderedComponentWithNextElement ReactNativeStack-dev.js:1859
_updateRenderedComponent ReactNativeStack-dev.js:1855
_performComponentUpdate ReactNativeStack-dev.js:1838
updateComponent ReactNativeStack-dev.js:1819
receiveComponent ReactNativeStack-dev.js:1784
receiveComponent ReactNativeStack-dev.js:1349
updateChildren ReactNativeStack-dev.js:2677
_reconcilerUpdateChildren ReactNativeStack-dev.js:2817
_updateChildren ReactNativeStack-dev.js:2852
updateChildren ReactNativeStack-dev.js:2849
receiveComponent ReactNativeStack-dev.js:2915
receiveComponent ReactNativeStack-dev.js:1349
_updateRenderedComponentWithNextElement ReactNativeStack-dev.js:1859
_updateRenderedComponent ReactNativeStack-dev.js:1855
_performComponentUpdate ReactNativeStack-dev.js:1838
updateComponent ReactNativeStack-dev.js:1819
receiveComponent ReactNativeStack-dev.js:1784
receiveComponent ReactNativeStack-dev.js:1349
_updateRenderedComponentWithNextElement ReactNativeStack-dev.js:1859
_updateRenderedComponent ReactNativeStack-dev.js:1855
_performComponentUpdate ReactNativeStack-dev.js:1838
updateComponent ReactNativeStack-dev.js:1819
receiveComponent ReactNativeStack-dev.js:1784
receiveComponent ReactNativeStack-dev.js:1349
_updateRenderedComponentWithNextElement ReactNativeStack-dev.js:1859
_updateRenderedComponent ReactNativeStack-dev.js:1855
_performComponentUpdate ReactNativeStack-dev.js:1838
updateComponent ReactNativeStack-dev.js:1819
receiveComponent ReactNativeStack-dev.js:1784
receiveComponent ReactNativeStack-dev.js:1349
_updateRenderedComponentWithNextElement ReactNativeStack-dev.js:1859
_updateRenderedComponent ReactNativeStack-dev.js:1855
_performComponentUpdate ReactNativeStack-dev.js:1838
updateComponent ReactNativeStack-dev.js:1819
receiveComponent ReactNativeStack-dev.js:1784
receiveComponent ReactNativeStack-dev.js:1349
_updateRenderedComponentWithNextElement ReactNativeStack-dev.js:1859
_updateRenderedComponent ReactNativeStack-dev.js:1855
_performComponentUpdate ReactNativeStack-dev.js:1838
updateComponent ReactNativeStack-dev.js:1819
performUpdateIfNecessary ReactNativeStack-dev.js:1787
performUpdateIfNecessary ReactNativeStack-dev.js:1357
runBatchedUpdates ReactNativeStack-dev.js:1483
perform ReactNativeStack-dev.js:1391
perform ReactNativeStack-dev.js:1391
perform ReactNativeStack-dev.js:1460
flushBatchedUpdates ReactNativeStack-dev.js:1491
closeAll ReactNativeStack-dev.js:1421
perform ReactNativeStack-dev.js:1397
batchedUpdates ReactNativeStack-dev.js:2106
enqueueUpdate$1 ReactNativeStack-dev.js:1496
enqueueUpdate ReactNativeStack-dev.js:1525
enqueueSetState ReactNativeStack-dev.js:1571
ReactComponent.setState react.development.js:167
onStateChange connectAdvanced.js:222
dispatch createStore.js:186
(anonymous) redux-logger.js:1
(anonymous) middleware.js:72
dispatch applyMiddleware.js:45
(anonymous) utils.js:265
(anonymous) proc.js:491
exec scheduler.js:25
flush scheduler.js:66
asap scheduler.js:39
(anonymous) channel.js:197
emit channel.js:38
(anonymous) middleware.js:73
(anonymous) persistStore.js:55
complete getStoredState.js:73
(anonymous) getStoredState.js:52
(anonymous) AsyncStorage.js:86
__invokeCallback MessageQueue.js:301
(anonymous) MessageQueue.js:118
__guard MessageQueue.js:228
invokeCallbackAndReturnFlushedQueue MessageQueue.js:117
(anonymous) debuggerWorker.js:71

@aksonov
Copy link
Owner

aksonov commented Jul 19, 2017

It is strange why I can't reproduce it with Example project, can you? Anyway error is gone when you make top-level App as stateless component, please check

@UlfR
Copy link

UlfR commented Jul 19, 2017

Confirm. There are no warns, if top-level component with Router in render is stateless and rendered only once.

@aksonov aksonov closed this as completed Jul 19, 2017
@necsoft
Copy link
Author

necsoft commented Jul 19, 2017

I'm sorry but I don't understand what do you mean with stateless render. How can I avoid that message in my example?

@compojoom
Copy link
Contributor

@aksonov would you mind commenting on this? What do you mean with top-level App as stateless component? I'm getting the same error as above and it is coming from mobx form the stacktrace.

@aksonov
Copy link
Owner

aksonov commented Jul 21, 2017

Check react docs about stateless components and check Example project:
const App = () => <Router>...

@necsoft
Copy link
Author

necsoft commented Jul 22, 2017

This is working now:

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  Button,
  View
} from 'react-native';

import {
  Scene,
  Router,
  Actions
} from 'react-native-router-flux';

const App = () => {
    return (
      <Router>
        <Scene key="root">
          <Scene key="home" component={Home} title="Home"/> 
          <Scene key="details" component={Details} title="Details"/>
        </Scene>
      </Router>
    );
}



class Home extends Component {
  render() {
    return (
      <View style={styles.container_home}>
        <Text style={styles.welcome}>
          Home Screen
        </Text>
        <Button
          onPress={()=>Actions.details()}
          title="Details"
          color="#ffffff"
        />
      </View>
    );
  }
}

class Details extends Component {
  render() {
    return (
      <View style={styles.container_details}>
        <Text style={styles.welcome}>
          Details Screen
        </Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container_home: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#333333',
  },
  container_details: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'gray',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
    color:'#FFC300'
  },
});

AppRegistry.registerComponent('react_native_router_flux', () => App);

@compojoom
Copy link
Contributor

I don't understand what I'm doing wrong.

This is my original code:

class App extends Component {

    renderBackButton(nav) {
       ...
        return nav.navigationState.index ? (
                <TouchableOpacity onPress={onPress} style={styles.backButtonStyle}>
                    {button}

                </TouchableOpacity>
            ) : null;
    }

    render() {
        let owner = this.props.owner, loggedIn;
        try {
            if (owner.user.user_id) {
                loggedIn = true;
            }
        }
        catch (e) {
            loggedIn = false;
        }

        return (
            <Router>
                <Scene key="root" headerMode="screen" cardStyle={styles.cardStyle}>
                    <Scene key="LoginOrRegister" hideNavBar component={LoginOrRegister}
                           initial={loggedIn ? false : true}
                           title="Login or register"/>
                    <Scene key="login" hideNavBar={true} component={Login} title="Login"/>
                    <Scene key="requestPassword" hideNavBar={true} component={RequestPassword} title="Passwort vergessen"/>
....
                </Scene>
            </Router>
        )
    }
}

const selector = (state) => {
    return {
        owner: state.owner
    }
};

export default connect(selector, actionCreators)(App);

And this is what I transformed it to:

const App = (owner) => {

	console.log(owner);
	let loggedIn;
	try {
		if (owner.user.user_id) {
			loggedIn = true;
		}
	}
	catch (e) {
		loggedIn = false;
	}
	return (
		<Router>
			<Scene key="root" headerMode="screen" cardStyle={styles.cardStyle}>
				<Scene key="LoginOrRegister" hideNavBar component={LoginOrRegister}
					   initial={loggedIn ? false : true}
					   title="Login or register"/>
				<Scene key="login" hideNavBar={true} component={Login} title="Login"/>
				<Scene key="requestPassword" hideNavBar={true} component={RequestPassword} title="Passwort vergessen"/>
......
			</Scene>
		</Router>
	)
}

class BlaBla extends Component {
	render() {
		return <App owner={this.props.owner}/>
	}
}

const selector = (state) => {
	return {
		owner: state.owner
	}
};

export default connect(selector, actionCreators)(BlaBla);

Any idea what I'm doing wrong?

@aksonov
Copy link
Owner

aksonov commented Jul 22, 2017 via email

@compojoom
Copy link
Contributor

@aksonov - I just did a little digging. Would you mind explaining why does the component need to be stateless?

I have an App component that initialises my state, loads the redux store and then passes it to the mainApp which renders the scenes.
The mainApp needs to know about part of the state in order to decide which scene to render first. So I'm connecting my mainApp to redux and passing it the part of the state it's interested in. The second that part of the state changes - I get the error. If I connect my component to redux, but subscribe to an empty state - then no error...
Why is it now a problem to have a state? one way around this is to pass the state as Prop to my mainApp like:


Then I can read the part of the state I'm interested in and set which scene to render first, but I don't understand why is it now no go to connect the router to the state in v4? My code worked fine with v3.

@Stophface
Copy link

I am having the same problem. As suggested rewriting it as stateless component is no option for me because I pass props down from another component.

@aksonov
Copy link
Owner

aksonov commented Aug 16, 2017

@Stophface Maybe you need to reconsider architecture of your app. react-navigation, for example, provides only static methods to create navigators - you don't have any way to pass props from other components runtime.

@Stophface
Copy link

Stophface commented Aug 17, 2017

@aksonov Basically I am writing this https://www.grok-interactive.com/blog/react-native-selection-list/ inside a DrawerNavigation from react navigation as a contentComponent. When I am, lets say, two screens "deep" as shown in the example, I need to close the DrawerNavigation on a Press of a Button. That only works when I pass down the props of this.props.navigation in order to call onRight={() => navigate('DrawerClose')}.

@AliYar-Khan
Copy link

This is working now:

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  Button,
  View
} from 'react-native';

import {
  Scene,
  Router,
  Actions
} from 'react-native-router-flux';

const App = () => {
    return (
      <Router>
        <Scene key="root">
          <Scene key="home" component={Home} title="Home"/> 
          <Scene key="details" component={Details} title="Details"/>
        </Scene>
      </Router>
    );
}



class Home extends Component {
  render() {
    return (
      <View style={styles.container_home}>
        <Text style={styles.welcome}>
          Home Screen
        </Text>
        <Button
          onPress={()=>Actions.details()}
          title="Details"
          color="#ffffff"
        />
      </View>
    );
  }
}

class Details extends Component {
  render() {
    return (
      <View style={styles.container_details}>
        <Text style={styles.welcome}>
          Details Screen
        </Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container_home: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#333333',
  },
  container_details: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'gray',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
    color:'#FFC300'
  },
});

AppRegistry.registerComponent('react_native_router_flux', () => App);

What was the issue ? Kindly explain !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants