react native check render method navigator - react-native

Trying to make a new app, I get error below from the code.
the component seesm to world
https://www.youtube.com/watch?v=QJ_iRLfehSU&index=3&list=PL7D-0n1z1EbgAoLu1n5wjcMLDDAQqXOMw
/**
* Sample React Native App
* https://github.com/facebook/react-native
* #flow
*/
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Navigator
} from 'react-native';
var Login = require("./app/components/Login");
class PioneerSales extends Component {
render() {
return (
<Navigator
initialRoute = {{
id: "Login"
}}
renderScene = {
this.navigatorRenderScene
}
/>
);
}
navigatorRenderScene(route, navigator){
_navigator = navigator;
if (route.id == "Login") {
return (<Login _navigator={_navigator} title="Login" />)
}
}
}
AppRegistry.registerComponent('PioneerSales', () => PioneerSales);
Any help would be appreciated.

It may be due to your Login component has not exposed out.It should be like this. Check your component. Then import this component like this
import Test from './app/xxx/Login'
export default class Test extends Component {
render() {
return (
<View style={stytles.mainStytle}>
</View>
)
}
}

Related

How to programmatically navigate in react native?

I have a screen named ChooseUser. And a file named ChooseUserScreen.js which I want to navigate to once signIn is done. But its not working. Its showing this error:
ReferenceError: Can't find variable: navigate
This is my code:
import React, { Component } from 'react';
import { Text, Block, Input, Button } from 'galio-framework';
import { StyleSheet, TouchableOpacity } from 'react-native';
class SignIn extends Component {
state = {
tochooseuser: false
}
signIn() {
this.setState({tochooseuser: true })
}
render() {
if (this.state.tochooseuser === true) {
navigate('ChooseUser')
}
return (
<Button round color="info" style={ styles.btn } onPress={ this.signIn.bind(this) }>Sign in</Button>
);
}
}
export default SignIn;
I managed to do it with
this.props.navigation.navigate('ChooseUser')
inside signIn()

Unable to load provider from react-redux module in react native

I am creating a slide bar, In that, I have used the react-redux library. When I call the class which contains the redux-code, it works fine. I want to show this slide bar after login. Therefore, with conditions (I set a state variable if user login successfully then only this page should get rendered), I tried to call the same file which shows a blank page. I printed the console log. I am able to print all the logs. But with conditions, I am not able to load the data.
I don't know much about react-redux.Can you assist me to resolve this?
My code is,
main.js,
import React, {Component} from 'react';
import {
StyleSheet,
Dimensions,
Platform,
View,
StatusBar,
DrawerLayoutAndroid,
} from 'react-native';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import reducer from '../Redux/reducers';
import { setNavigator, setActiveRoute } from "../Redux/actions";
import DrawerContent from '../Navigation/DrawerContent';
import Toolbar from '../Navigation/Toolbar';
import AppNavigation from '../Navigation/AppNavigation';
import { bgStatusBar, bgDrawer } from '../global.styles';
let store = createStore(reducer);
/* getDrawerWidth Default drawer width is screen width - header width
* https://material.io/guidelines/patterns/navigation-drawer.html
*/
const getDrawerWidth = () => Dimensions.get('window').width - (Platform.OS === 'android' ? 56 : 64);
export default class Main extends Component {
constructor() {
super();
this.drawer = React.createRef();
this.navigator = React.createRef();
}
componentDidMount() {
store.dispatch(setNavigator(this.navigator.current));
}
openDrawer = () => {
this.drawer.current.openDrawer();
};
closeDrawer = () => {
this.drawer.current.closeDrawer();
};
getActiveRouteName = navigationState => {
if (!navigationState) {
return null;
}
const route = navigationState.routes[navigationState.index];
// dive into nested navigators
if (route.routes) {
return getActiveRouteName(route);
}
return route.routeName;
};
render() {
return (
<Provider store={store}>
<DrawerLayoutAndroid
drawerWidth={getDrawerWidth()}
drawerPosition={DrawerLayoutAndroid.positions.Left}
renderNavigationView={
() => <DrawerContent closeDrawer={this.closeDrawer} />
}
ref={this.drawer}
>
<View style={styles.container}>
<StatusBar
translucent
animated
/>
<Toolbar showMenu={this.openDrawer} />
<AppNavigation
onNavigationStateChange={(prevState, currentState) => {
const currentScreen = this.getActiveRouteName(currentState);
store.dispatch(setActiveRoute(currentScreen));
}}
ref={this.navigator}
/>
</View>
</DrawerLayoutAndroid>
</Provider>
);
}
}
Login.js
import Main from './main';
render() {
return (
<View>
{this.state.isLoggedIn ?
<Main/>
:
<ChangePassword isUpdatePassword={this.state.isUpdatePassword} callLogin={this.callLogin}/>
);
}
}
If I just call Main class inside render method it works. But It does not work with conditions.

Undefined Unstated Container in a React Native Component using React Navigation

My problem is That I want to access a Container in a component but it seems to be undefined.
undefined alert image
I am using Unstated and as you can see this is my code in the container file (login-container.js):
import { Container } from 'unstated'
class LoginContainer extends Container {
constructor(props){
super(props)
this.state = {
stepNumber: 0,
}
}
}
export default new LoginContainer()
And this is app.js:
import React, { Component } from 'react'
import { createStackNavigator, createSwitchNavigator } from 'react-navigation'
import { Provider } from 'unstated'
import LoginContainer from './containers/login-container'
import Home from './screens/home'
import Splash from './screens/splash'
import Login from './screens/login'
import Intro from './screens/intro'
export default class App extends Component {
render() {
return (
<Provider inject={[LoginContainer]}>
<AuthStack/>
</Provider>
)
}
}
const SplashStack = createStackNavigator(...)
const AppStack = createStackNavigator(...)
const AuthStack = createStackNavigator(
{
Intro: { screen: Intro},
Login: { screen: Login}
},
{
headerMode: "none",
initialRouteName: "Intro"
}
)
const SwitchNavigator = createSwitchNavigator(...)
And this would be login.js:
import React, { Component } from 'react'
import { Text, View } from 'react-native'
export default class Login extends Component {
constructor(props){
super(props)
}
render() {
// const { state: {stepNumber} } = this.props.loginContainer
alert(this.props.LoginContainer)
return (
<View>
<Text> someText </Text>
</View>
)
}
}
I previously tried to use Subscribe component to inject the container to my app but I got the same thing I am getting here.
Using
- react-native 0.58.6
- react-navigation 2.13.0 (due to some bugs in v3)
- unstated 2.1.1
What's really great about Unstated is how simple it is to implement.
Just wrap your render component in Unstated's <Subscribe to></Subscribe> tags and you're good to go. Whenever you setState() in the Container, all Components that Subscribe to it get re-rendered with the Container's updated state property values available to them.
import React, { Component } from 'react';
import { Text, View } from 'react-native';
import { Subscribe } from 'unstated';
import LoginContainer from './containers/login-container';
export default class Login extends Component {
constructor(props){
super(props)
}
render() {
return (
<Subscribe to={[LoginContainer, AnotherContainer]}>
{(container, another) => (
<View>
<Text>{container.state.stepNumber}</Text>
</View>
})
</Subscribe>
);
}
}
UPDATE: Or do it in this HOC way. After creating this:
WithUnstated.js
import React, { PureComponent } from "react";
import { Subscribe } from "unstated";
import DefaultStore from "../store/DefaultStore";
const withUnstated = (
WrappedComponent,
Stores = [DefaultStore],
navigationOptions
) =>
class extends PureComponent {
static navigationOptions = navigationOptions;
render() {
return (
<Subscribe to={Stores}>
{(...stores) => {
const allStores = stores.reduce(
(acc, v) => ({ ...acc, [v.displayName]: { ...v } }),
{}
);
return <WrappedComponent {...allStores} {...this.props} />;
}}
</Subscribe>
);
}
};
export default withUnstated;
Then wrap your component like so:
import React, { Component } from 'react';
import { Text, View } from 'react-native';
import { Subscribe } from 'unstated';
import LoginContainer from './containers/login-container';
import AnotherContainer from './containers/another-container';
class Login extends Component {
constructor(props){
super(props)
}
render() {
const {LoginContainer: container} = this.props;
return (
<View>
<Text>{container.state.stepNumber}</Text>
</View>
);
}
}
export default withUnstated(Login, [LoginContainer, AnotherContainer])

Navigation in React Router v4 Native Not Changing Scenes

I'm using React Router for a React Native app. Not sure what I'm missing here but I install react-router-native and require the history package, and setup a couple methods that just push a new route onto the stack but nothing happens. I console.log('clicked'); to check that it's firing and it is so not sure what's wrong.
import React, { Component } from 'react';
import { View } from 'react-native';
import Splash from './Splash';
import createHistory from 'history/createMemoryHistory';
const history = createHistory();
class SplashContainer extends Component {
goToLogin = () => {
history.push('/Login');
}
goToRegister = () => {
history.push('/SignUp');
}
render () {
console.log(history)
return (
<Splash
goToLogin={this.goToLogin}
goToRegister={this.goToRegister}
/>
);
}
}
export default SplashContainer;
import React from 'react';
import { StyleSheet, View, Text } from 'react-native';
import { Button } from 'native-base';
import { Link } from 'react-router-native';
import PropTypes from 'prop-types';
const Splash = (props) => {
console.log(props)
return (
<View style={styles.container}>
<Button light block onPress={props.goToLogin}>
<Text>Login</Text>
</Button>
<Button dark block bordered style={{marginTop: 10}} onPress={props.goToRegister}>
<Text>Register</Text>
</Button>
</View>
);
}
Splash.propTypes = {
goToLogin: PropTypes.func.isRequired,
goToRegister: PropTypes.func.isRequired
}
export default Splash;
I don't know your Router config, but your methods should be:
goToLogin = () => {
const { history } = this.props
history.push('/Login');
}
history will passed down via props of component inside Router's stack.

Passing in action creators to react-navigation

I'm using the new react-navigation library for a React Native application I'm building. I'm having an issue with passing down my ActionCreators from my Nav component down to its scenes.
I have an AppContainer that wraps the entire application.
import React, { Component } from 'react';
import { DrawerNavigator, addNavigationHelpers } from 'react-navigation';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { ActionCreators } from '../actions';
import DashboardContainer from './DashboardContainer';
import CustomersContainer from './CustomersContainer';
const ApplicationNavigation = DrawerNavigator({
Dashboard: { screen: DashboardContainer },
Customers: { screen: CustomersContainer },
});
class AppContainer extends Component {
render() {
return (
<ApplicationNavigation />
);
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(ActionCreators, dispatch);
}
export default connect(() => { return {} }, mapDispatchToProps)(AppContainer);
Here is the CustomerContainer:
import React, {Component} from 'react';
import {View, Text, Button} from 'react-native';
export default class CustomerContainer extends Component {
btnPressed() {
this.props.listCustomers()
}
render () {
return (
<View style={{marginTop: 40}}><Text>Customer</Text>
<Button onPress={() => this.btnPressed()} title="Press Me!" />
</View>
);
}
}
Now I'm trying to call an action within my CustomerContainer this.props.listCustomers(). The problem is the ActionCreator props aren't being passed down to the screens. I've tried doing adding the screenProps prop to the ApplicationNavigation component:
But for some reason when I do this my app doesn't display any screens its just blank with no errors.
UPDATE
So I updated my CustomerContainer file:
import React, {Component} from 'react';
import {View, Text, Button} from 'react-native';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { ActionCreators } from '../actions';
class CustomerContainer extends Component {
btnPressed() {
console.log(this.props.listCompanyCustomers())
}
render () {
return (
<View style={{marginTop: 40}}><Text>Customer</Text>
<Button onPress={() => this.btnPressed()} title="Press Me!" />
</View>
);
}
}
function mapStateToProps(state) {
return {
companyCustomers: state.companyCustomers
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(ActionCreators, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(CustomerContainer);
This now works; however this feels like the incorrect way to go about this.
What redux connect basically does is:
Wrap your component
Declare contextProps to get access to dispatch
pass the dispatch to your component props.
If you pass the connect mapDispatchToProps, then it creates the mapping of the methods to dispatch.
So if you connect you AppContainer, its children won't get these dispatch methods, unless AppContainer passes them to its children (but this what connect comes to prevent).
So to sum up, you should connect any component that needs to use dispatch, otherwise it won't get it.
If you don't want to copy paste the mapDispatchToProps, you can just delete it and use this.props.dispatch instead:
import { ActionCreators } from '../actions';
class CustomerContainer extends Component {
btnPressed() {
this.props.dispatch(ActionCreators.listCompanyCustomers());
}
render () {
return (
<View style={{marginTop: 40}}><Text>Customer</Text>
<Button onPress={() => this.btnPressed()} title="Press Me!" />
</View>
);
}
}