Error: Check the render method with react-redux connect() - react-native

I'm trying to learn redux with react-native, so I did some examples, but for everyone, even though they are different, I'm getting the same error.
My code is like this:
index.js:
import { AppRegistry } from 'react-native';
import App from './src/app';
AppRegistry.registerComponent('reduxExample', () => App);
src/app.js:
import React, { Component } from 'react';
import { Provider } from 'react-redux';
import { Store } from './store';
import Home from './components/home';
export default props => (
<Provider store={Store}>
<Home />
</Provider>
)
src/components/home.js:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { View, Text, Button, Input } from 'react-native';
class Home extends Component {
render() {
const { newValue } = this.props;
return (
<View>
<Input type='text' />
<Button>
Click me!
</Button>
<Text>{newValue}</Text>
</View>
);
}
}
const mapStateToProps = store => ({
newValue: store.clickState.newValue
});
export default connect(mapStateToProps)(Home)
src/store/index.js:
import { createStore } from 'redux';
import { Reducers } from '../reducers';
export const Store = createStore(Reducers);
The rest I believe they do not have to deal with the problem but if I need to put the code.

There is no <Input type='text' /> tag in react native. There is only a <TextInput /> tag.

Related

undefined is not a function evaluating 'this.props.dispatch

I try to test redux. I have component Main that redirects to TestRedux. TestRedux componenent make a dispatch and redirects to TestRedux2 when click on a button.
TestRedux and TestRedux2 are the same, I have made a copy/paste, just change values. TestRedux dispatch correctly, but testRedux2 trigger an error.
Do you know what is the cause of the problem ?
// TestRedux
import React from 'react';
import { View, Text, Button, Alert } from 'react-native';
import { ADD_RES } from "../Constants/action-types";
import {addResa} from "../Actions/actions";
import { connect } from 'react-redux'
import Store from '../Store/store'
const mapStateToProps = state => ({ date: state.date })
export class TestRedux extends React.Component {
render() {
this.props.dispatch(addResa(1));
return (
<View>
<Button
onPress={() => { this.props.navigation.navigate('TestRedux2') }}
title='test'
/>
</View>
)
}
}
export default connect(mapStateToProps)(TestRedux)
// TestRedux2
import React from 'react';
import { View, Text, Button, Alert } from 'react-native';
import { ADD_RES } from "../Constants/action-types";
import {addResa} from "../Actions/actions";
import { connect } from 'react-redux'
import Store from '../Store/store'
const mapStateToProps = state => ({ date: state.date })
export class TestRedux2 extends React.Component {
render() {
this.props.dispatch(addResa(2));
return (
<View>
<Button
onPress={() => { this.props.navigation.navigate('TestRedux') }}
title='test2'
/>
</View>
)
}
}
export default connect(mapStateToProps)(TestRedux2)
Store is:
import { createStore } from "redux"; // without redux persist
import { persistCombineReducers } from 'redux-persist'
import storage from 'redux-persist/lib/storage'
import resaReducer from "../Reducers/resaReducer";
const rootPersistConfig = {
key: 'root',
storage: storage
}
const Store = createStore(persistCombineReducers(rootPersistConfig, {resaReducer}))
export default Store;
````
Dispatch an action or pass null to connect. See if the issue continues.
export default connect(mapStateToProps)(TestRedux2)
to
export default connect(mapStateToProps, null)(TestRedux2)

undefined is not a function (evaluating 'navigation.dispatch')

I am trying to navigate to the first page after user logout!
and getting this error:
undefined is not a function (evaluating 'navigation.dispatch').
my action creator code is as follows:
import {NavigationActions} from 'react-navigation';
import {AsyncStorage} from 'react-native';
import {applyMiddleware as dispatch} from "redux";
export const userRemove = (navigation) => {
AsyncStorage.removeItem('user');
const navigateAction = NavigationActions.navigate({
routeName: 'First',
props: {}
});
navigation.dispatch(navigateAction);
};
I have called this action from sideBar of component. The component code is correct since that AsyncStorage.removeItem('user') is working correctly!
sorry for bad grammar. I can't write in english better than this error message here
my component code here:
import React, {Component} from 'react';
import {
Container,
Content,
Footer,
FooterTab,
Button,
Icon
} from 'native-base';
import {userRemove} from '../actions/sideBarAction';
import {connect} from "react-redux";
import {bindActionCreators} from "redux";
class SideBar extends Component {
constructor(props) {
super(props);
}
logout() {
userRemove(this.props.navigation);
}
render() {
return (
<Container>
<Content>
...
</Content>
<Footer>
<FooterTab>
<Button onPress={this.logout.bind(this)}>
<Icon name="logout"/>
</Button>
</FooterTab>
</Footer>
</Container>
)
}
}
const mapStateToProps = state => {
return {
username: state.home.username,
password: state.home.password,
score: state.home.score,
}
};
const mapDispatchToProps = dispatch => {
return Object.assign({dispatch: dispatch},
bindActionCreators(userRemove, dispatch));
};
connect(mapStateToProps, mapDispatchToProps)(SideBar);
Is your component added to you main navigator? If not see if you can add.
You can also wrap your component with withNavigation function from react-navigation. That will make sure you have valid navigation prop.
import { withNavigation } from react-navigation;
...
connect(mapStateToProps, mapDispatchToProps)(withNavigation(SideBar));
Alternatively, you may pass this.props.navigation from parent component too.

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.

React-Native Error: Element type is invalid()

When I launch my app on iOS I get that error:
Element type is invalid: expected a string or class/function, but got: undefined. You likely to forgot to export your component from the file it's defined in.
Check the render method of LoginForm
Here is my App.js:
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import firebase from 'firebase';
import reducers from './reducers';
import LoginForm from './components/LoginForm';
const store = createStore(reducers);
class App extends Component {
componentWillMount() {
const config = {
apiKey: 'dawdawdas',
authDomain: 'dasdasd',
databaseURL: 'dasdasd',
projectId: 'dasd',
storageBucket: 'dsdasd',
messagingSenderId: 'dasdasda'
};
firebase.initializeApp(config);
}
render() {
return (
<Provider store={store}>
<LoginForm />
</Provider>
);
}
}
export default App;
And LoginForm.js:
import React, { Component } from 'react';
import { Card, CardSectiion, Input, Button } from './common';
export default class LoginForm extends Component {
render() {
return (
<Card>
<CardSectiion>
<Input
label="Email"
placeholder="User#example.com"
/>
</CardSectiion>
<CardSectiion>
<Input
secureTextEntry
label="Password"
placeholder="Password"
/>
</CardSectiion>
<CardSectiion>
<Button>
Login
</Button>
</CardSectiion>
</Card>
);
}
}
I'm exporting the LoginForm class, but get this error.
What I'm doing wrong?
import { Card, CardSectiion, Input, Button } from './common';
The problem seems occured in this part.Check out that each component was exported correctly.

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>
);
}
}