NavigatorIOS not rendering initialroute - react-native

I pretty much copied and pasted the demo code from Facebook, but the initialRoute component does not render. Answers like setting flex:1 as suggested by similar questions didn't work for me. Any tips?
import React, { Component } from 'react';
import {
StyleSheet,
NavigatorIOS,
StatusBar,
AppRegistry,
View,
Text,
TouchableHighlight,
} from 'react-native';
import NativeThing from './components/ReactNative';
export default class ListsList extends Component {
render() {
return (
<NavigatorIOS
initialRoute={{
component: MyScene,
title: 'My Initial Scene',
}}
style={{flex: 1}}
/>
);
}
}
class MyScene extends Component {
_onForward = () => {
this.props.navigator.push({
title: 'Scene ' + nextIndex,
});
}
render() {
return (
<View>
<Text>Current Scene: { this.props.title }</Text>
<TouchableHighlight onPress={this._onForward}>
<Text>Tap me to load the next scene</Text>
</TouchableHighlight>
</View>
)
}
}
var styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F5FCFF',
}
});
AppRegistry.registerComponent('ListsList', () => ListsList);

The navigation bar by default overlaps the content of MyScene component. This is the default behaviour of the NavigatorIOS with a translucent
navigation bar.
So you have two options:
Add style paddingTop: 64 to the View of MyScene.
Add property translucent={ false } to the NavigatorIOS

Related

React Native - invalid prop children

I've created a few components. One of them should allow nesting however it inexplicably does not (inexplicable because I couldn't find any posts with quite this problem)
There is one image required to run this (it can be replaced with anything)
import React, {Component} from 'react';
import PropTypes from 'prop-types';
import { View, StatusBar, StyleSheet, ImageBackground } from 'react-native';
export class PhonyStatusBar extends Component {
render () {
return (
<View style={styles.statusBar} />
);
}
}
export class HomeScreen extends Component {
static propTypes = {
children: PropTypes.string
}
render () {
return (
<View>
{this.props.children}
</View>
);
}
}
export class AppGrid extends Component {
render () {
return (
<View />
);
}
}
export default class App extends Component {
render() {
return (
<View>
{/* hide system status bar */}
<StatusBar hidden={true} />
<PhonyStatusBar />
{/* throw in our own status bar */}
<HomeScreen>
<View />
</HomeScreen>
</View>
);
}
}
const styles = StyleSheet.create({
backgroundImage: {
width:'100%',
height:'100%',
},
statusBar: {
width: '100%',
height: 25.33,
backgroundColor: 'rgba(255, 157, 0, 0.5)'
},
});
In react children is a built in prop, already defined by the library, for components. This is not a prop that you should be defining manually. See this for more detail: https://reactjs.org/docs/jsx-in-depth.html#children-in-jsx
Try removing:
static propTypes = {
children: PropTypes.string
}
from HomeScreen to resolve the issue.

Camera does not display, state transition issue, react-native

I've been trying to save an asyncstorage item, on touchableopacity onPress, then navigate to a react-native-camera screen.
Problem is: Camera screen get blank. I got the following 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 anti-pattern, but can be moved to 'componentWillMount'.
Warning points to lines 27, 36 and 41 (at AddParameters class)
Here is the code:
AddParameters.js
import React, { Component } from 'react';
import {
Text,
AsyncStorage,
View,
TouchableOpacity,
} from 'react-native';
class AddParameters extends Component {
constructor() {
super()
this.state = {
localIds: [
"data1",
"data2",
"data3",
"data4",
"data5",
"data6"
],
}
}
renderScreen = () => {
return (
<TouchableOpacity onPress={this._AddParameter(this.state.localIds[0])}>
<Text>Click Me</Text>
</TouchableOpacity>
);
}
_AddParameter = (ParameterId) => {
const { navigate } = this.props.navigation;
AsyncStorage.setItem("myparam", ParameterId);
navigate("CameraScreen");
}
render() {
return (
this.renderScreen()
);
}
}
export default AddParameters;
CameraScreen.js
'use strict';
import React, { Component } from 'react';
import {
AppRegistry,
Dimensions,
StyleSheet,
Text,
View,
Image,
AsyncStorage,
} from 'react-native';
import Camera from 'react-native-camera';
class CameraScreen extends Component {
constructor(props) {
super(props);
this.state = {
mystate: '',
};
}
renderCamera = () => {
return (
<Camera
ref={(cam) => {
this.camera = cam;
}}
style={stylesCamera.container}
aspect={Camera.constants.Aspect.fill}>
</Camera>
);
}
render() {
return (
this.renderCamera()
);
}
}
const stylesCamera = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "transparent",
},
});
export default CameraScreen;
Any explanation would be helpfull. Thanks in advance.
On your AddParameters file try changing this:
<TouchableOpacity onPress={this._AddParameter(this.state.localIds[0])}>
To:
<TouchableOpacity onPress={() => this._AddParameter(this.state.localIds[0])}>

Navigated React Native component is not rendered properly after updating its parent's state

I have a parent component with Navigator and 2 child components.
In parent component I have a method that updates the height of a View it has, which I pass to child components, allowing them to refresh the state of the parent once they are mounted.
When I navigate directly to second child, then call this method in second child's componentDidMount, the second child is re-rendered properly.
However, when I navigate from first child to second, the second child is not re-rendered as expected.
Parent:
import React, { Component } from 'react';
import {
StyleSheet,
Text,
Navigator,
View
} from 'react-native';
import FirstChild from './FirstChild';
import SecondChild from './SecondChild';
export default class Parent extends Component {
constructor(props) {
super(props);
this.setViewHeight = this.setViewHeight.bind(this);
this.state = {
viewHeight : 200
}
}
renderScene(route, navigator) {
var child = route.name == 'FirstChild' ?
<FirstChild navigator={navigator} heightSetter={this.setViewHeight}/> :
<SecondChild navigator={navigator} heightSetter={this.setViewHeight}/>;
return (
<View style={styles.container}>
<View style={[styles.dynamicView, {height: this.state.viewHeight}]}/>
{child}
</View>
)
}
render() {
return (
<Navigator
ref='navigator'
initialRoute={{ name: 'FirstChild' }}
renderScene={(route,navigator)=>this.renderScene(route,navigator)}
/>
);
}
setViewHeight() {
this.setState({
viewHeight: 100
})
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignSelf: 'stretch',
justifyContent: 'flex-start',
alignItems: 'center',
},
dynamicView: {
alignSelf: 'stretch',
backgroundColor: 'rgba(100,100,200, 0.5)'
}
});
First Child:
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
TouchableOpacity
} from 'react-native';
export default class FirstChild extends Component {
constructor(props) {
super(props)
}
render() {
return (
<TouchableOpacity style={styles.child} onPress={() => this.props.navigator.push({name: 'SecondChild'}) }>
<View style={styles.child}>
<Text>FIRST</Text>
</View>
</TouchableOpacity>
);
}
}
const styles = StyleSheet.create({
child: {
height: 200,
alignSelf: 'stretch',
backgroundColor: 'rgba(200,100,100,0.5)'
}
});
Second Child:
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View
} from 'react-native';
export default class SecondChild extends Component {
constructor(props) {
super(props)
}
componentDidMount() {
this.props.heightSetter();
}
render() {
return (
<View style={styles.child}>
<Text>Second</Text>
</View>
);
}
}
const styles = StyleSheet.create({
child: {
height: 200,
alignSelf: 'stretch',
backgroundColor: 'rgba(200,100,100,0.5)'
}
});
The question you are putting is not clear actually. What is the behavior that you got? Without clear picture of that it's not possible to answer your question but can tell you one thing that is
Using the navigation which is built in to react native is little complex and when there are many scenes to go through it doesn't support at all.
You can use navigation library like react-native router flux, which will definitely help you solve the issue you have got.
Here is the link,
https://github.com/aksonov/react-native-router-flux

ReactNative navigation

I'm having a great deal of trouble implementing a navigationsystem for my ReactNative app. Here's the index.js:
class Test extends Component {
render() {
const routes = [
{title: 'LoginScreen', index: 0},
{title: 'RegisterScreen', index: 1},
];
return (
<Navigator
initialRoute={routes[0]}
initialRouteStack={routes}
renderScene={(route, navigator) =>
<TouchableHighlight onPress={() => {
navigator.push(routes[1]);
}}>
<Text>Hello {route.title}!</Text>
</TouchableHighlight>
}
style={{padding: 100}}
/>
)
}
}
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
} else {
}
});
At the moment I have simply written a navigation straight off the docs. But I would want it to transition to another screen inside the if statements when checking for a Firebase user. So transitioning to one scene if a user exists and another scene if not.
I find the documentation of this very poor, so I can't even build a basic idea of how to modify this method of transitioning (seems to be endless ways of doing it, sigh..) into working to my situation.
You can definitely use the below example, It hops onto screens by 2 if he found user or hops onto screens by 1.
Assuming user already present
1. index.android.js
import React,{Component} from 'react';
import{
AppRegistry,
StyleSheet,
Text,
ScrollView,
Navigator,
View,
} from 'react-native';
import Navigation from './navigation'
export default class Example extends Component{
constructor(){
super();
this.state={
username: 'ABC',
}
}
render() {
var nextIndex
return (
<Navigator
initialRoute={{ title: 'My Initial Scene', index: 0 }}
renderScene={(route, navigator) =>
<Navigation
title={route.title}
onForward={() => {
if(this.state.username)
nextIndex = route.index + 2 ;
else
nextIndex = route.index + 1 ;
navigator.push({
title: 'Scene ' + nextIndex,
index: nextIndex,
});
}}
onBack={() => {
if (route.index > 0) {
navigator.pop();
}
}}
/>
}
/>
);
}
}
AppRegistry.registerComponent('Example', () => Example);
2. navigation.js
import React,{Component} from 'react';
import{
StyleSheet,
Text,
Navigator,
TouchableHighlight,
View,
} from 'react-native';
export default class Navigation extends Component{
constructor(props) {
super(props)
}
render() {
return (
<View>
<Text>Current Scene: {this.props.title}</Text>
<TouchableHighlight onPress={this.props.onForward}>
<Text>Tap me to load the next scene</Text>
</TouchableHighlight>
<TouchableHighlight onPress={this.props.onBack}>
<Text>Tap me to go back</Text>
</TouchableHighlight>
</View>
)
}
}
This is the working example for RN 0.40.0

React Native Navigator : Expected a component class, got [object Object]

the error which is shown in the title gets displayed when I try to load a new Component through the Navigator component.
My View with the Navigator component looks as following:
render(){
return(
<Navigator
initialRoute={{name: 'Feed', component: Feed}}
renderScene={(route, navigator) => {
if(route.component){
return React.createElement(route.component, {navigator, ...this.props})
}
}
}
/>
)
}
}
The initialRoute renders the correct View perfectly.
The child Component Feed that gets rendered contains a list of Buttons which update the Navigator and cause it to render a new component as following:
updateRoute(route){
this.props.globalNavigator(route)
this.props.navigator.push({
name: route.displayLabel,
component: route.label
})
}
render(){
return(
<View style={styles.bottomNavSection}>
{
this.state.navItems.map((n, idx) => {
return(
<TouchableHighlight
key={idx}
style={this.itemStyle(n.label, 'button')}
onPress={this.updateRoute.bind(this, n)}
>
<Text
style={this.itemStyle(n.label, 'text')}
>
{n.displayLabel}
</Text>
</TouchableHighlight>
)
})
}
</View>
)
}
Note that the function updateRoute(route) receives the name of the new component as following: onPress={this.updateRoute.bind(this, n)}. Where n equals to {displayLabel: 'Start', label: 'Feed', icon: ''}, for example.
Edit
Content of my Profil.js Component:
import React, { Component } from 'react'
import ReactNative from 'react-native'
import API from '../lib/api'
import BottomNavigation from '../components/BottomNavigation'
const {
ScrollView,
View,
Text,
TouchableHighlight,
StyleSheet,
} = ReactNative
import { connect } from 'react-redux'
class Profil extends Component {
constructor(props){
super(props)
}
render(){
return(
<View style={styles.scene}>
<ScrollView style={styles.scrollSection}>
<Text>Profil</Text>
</ScrollView>
<BottomNavigation {...this.props} />
</View>
)
}
}
const styles = StyleSheet.create({
scene: {
backgroundColor: '#0f0f0f',
flex: 1,
paddingTop: 20
},
scrollSection: {
flex: .8
}
})
function mapStateToProps(state){
return {
globalRoute: state.setGlobalNavigator.route
}
}
export default connect(mapStateToProps)(Profil)
The issue was that onPress={this.updateRoute.bind(this, n)} wasn't containing the proper component reference but instead was containing the component name as String.
Fixed it by altering the function :
updateRoute(route){
this.props.globalNavigator(route)
this.props.navigator.push({
name: route.displayLabel,
component: route.component
})
}
and enhancing the state with the component reference and importing the component in the beginning of the document.
this.state = {
navItems: [
{displayLabel: 'Start', label: 'Feed', icon: start, component: Feed},
]
}
I think you forget to export your component.