Reputation:
I am trying to make user login in my application through react redux but it gives error as
TypeError: undefined is not an object (evaluating 'state.user_name')
app.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import AppDrawer from './drawerNavigator.js';
import MainNavigator from './screens/stackNavigator'
import { createStore } from 'redux'
import { Provider } from 'react-redux'
initialState = {
first_name:"",
last_name: "",
user_name: "",
password: "",
}
const reducer = (state = initialState, action) =>{
switch (action.type) {
case 'SIGN_UP':
return
{first_name: state.first_name = action.payload.first_name}
{last_name: state.last_name = action.payload.last_name}
{user_name: state.user_name = action.payload.user_name}
{password: state.password = action.payload.password}
console.log("signUp");
case 'LOG_IN':
return
JSON.stringify(action.payload);
}
return state
}
const store = createStore(reducer);
export default class App extends React.Component {
constructor(props){
super(props);
}
render() {
return (
<>
<Provider store={store}>
< MainNavigator/>
</Provider>
</>
);
}
}
Login.js
import React from 'react';
import { StyleSheet, Text, View, Button, TextInput, Image, TouchableHighlight } from 'react-native';
import { connect } from 'react-redux';
import axios from 'axios';
import { NavigationActions } from 'react-navigation';
import { Actions } from 'react-native-router-flux';
class LogIn extends React.Component {
state = {
user: "",
pwd: "",
}
render(){
const navigation = this.props.navigation;
return(
<View style={styles.container}>
<View style={styles.inputContainer}>
<TextInput style={styles.inputs}
placeholder="User Name"
underlineColorAndroid='transparent'
onChangeText={(text)=>this.setState({user: text})}/>
</View>
<View style={styles.inputContainer}>
<TextInput style={styles.inputs}
placeholder="Password"
secureTextEntry={true}
underlineColorAndroid='transparent'
onChangeText={(text)=>this.setState({pwd: text})}/>
</View>
<View style={styles.btn}>
<TouchableHighlight style={[styles.buttonContainer, styles.loginButton]} onPress = {()=>this.props.logIn(this.state)}>
<Text style={styles.loginText}>Login</Text>
</TouchableHighlight>
<TouchableHighlight style={styles.buttonContainer}>
<Text>Forgot your password?</Text>
</TouchableHighlight>
<TouchableHighlight style={[styles.buttonContainer, styles.loginButton]} onPress = {()=>navigation.navigate('SignUp')}>
<Text>Register here</Text>
</TouchableHighlight>
</View>
</View>
);
}
}
const mapStateToProps = (state) =>{
return {
user_name: state.user_name,
password: state.password
}
}
const mapDispatchToProps = (dispatch,ownProps) =>{
return{
logIn: (text) => {
if(text.user == ""){
alert("Enter user name");
}
else if(text.pwd == ""){
alert("Enter Password");
}
else {
var body = {email: text.user,password: text.pwd}
console.log("body",body);
axios.post('http://user/login',body)
.then(res=>{
console.log("res",res);
dispatch({ type: 'LOG_IN',payload: res});
ownProps.navigation.navigate('AppDrawer');
},err=>{
alert(err);
})
}
}
}
}
export default connect(mapStateToProps,mapDispatchToProps)(LogIn)
signUp.js
import React from 'react';
import { StyleSheet, Text, View, Button, TextInput, Picker, TouchableOpacity, Image, ScrollView, TouchableHighlight } from 'react-native';
import { AppRegistry } from "react-native";
import { connect } from 'react-redux';
import axios from 'axios';
class SignUp extends React.Component {
state = {
first_name:"",
last_name: "",
user_name: "",
password: "",
}
render() {
return (
<View style={styles.container}>
<View style={styles.inputContainer}>
<TextInput style={styles.inputs}
placeholder="First Name"
underlineColorAndroid='transparent'
onChangeText={(text)=>this.setState({first_name: text})}/>
</View>
<View style={styles.inputContainer}>
<TextInput style={styles.inputs}
placeholder="Last Name"
keyboardType="email-address"
underlineColorAndroid='transparent' onChangeText={(text)=>this.setState({last_name: text})}/>
</View>
<View style={styles.inputContainer}>
<TextInput style={styles.inputs}
placeholder="User Name"
underlineColorAndroid='transparent'
onChangeText={(text)=>this.setState({user_name: text})}/>
</View>
<View style={styles.inputContainer}>
<TextInput style={styles.inputs}
placeholder="Password"
underlineColorAndroid='transparent'
secureTextEntry={true}
onChangeText={(text)=>this.setState({password: text})}/>
</View>
<View style={styles.btn}>
<TouchableHighlight style={[styles.buttonContainer, styles.loginButton]} onPress={()=>this.props.signUp(this.state)}>
<Text style={styles.loginText}>Register</Text>
</TouchableHighlight>
</View>
</View>
);
}
}
function mapStateToProps (state){
return {
first_name: state.first_name,
last_name: state.last_name,
user_name: state.user_name,
password: state.password,
}
}
function mapDispatchToProps(dispatch,ownProps){
return{
signUp: (text) => {
if (text.first_name=="") {
alert("Enter First Name");
} else if(text.last_name == ""){
alert("Enter Last Name");
}
else if(text.password == ""){
alert("Enter Password");
}
else if(text.user_name == ""){
alert("Enter User_name");
}
else {
var body = {first_name: text.first_name,last_name: text.last_name,user_name: text.user_name,password: text.password}
console.log("body",body);
axios.post('http://user/signup',body)
.then(res=>{
dispatch({ type: 'SIGN_UP', payload: body})
console.log({msg: 'added'});
ownProps.navigation.navigate('Login')
},err=>{
alert(err);
})
}
}
}
}
export default connect(mapStateToProps,mapDispatchToProps)(SignUp)
the error is located at Login.js in mapStateToProps() method my state in App.js is having user_name but it is not getting rendered in Login.js
Upvotes: 0
Views: 773
Reputation: 436
Your reducer should look this
const reducer = (state = initialState, action) =>{
switch (action.type) {
case 'SIGN_UP':
return { ...action.payload };
case 'LOG_IN':
return JSON.stringify(action.payload);
default:
return state;
}
}
and use semicolon end of statement missing it will create problems in some cases.
Upvotes: 0
Reputation: 1426
You got specific error here. JS will evaluate code below
case 'SIGN_UP':
return
{first_name: state.first_name = action.payload.first_name}
...
as
case 'SIGN_UP':
return undefined;
{first_name: state.first_name = action.payload.first_name}
...
Here is the live example
const testReturn = () => {
return
{ a: 2 }
}
console.log(testReturn())
While properly placed symbol {
works just fine
const testReturn = () => {
return {
a: 2
}
}
console.log(testReturn())
The same problem you have in your LOG_IN
case
return
JSON.stringify(action.payload)
Upvotes: 1