Reactjs: TypeError: Cannot read property ‘posts’ of undefined

In order to connect my Posts form to API When I try to write anything in Fields it displays me following error :-

enter image description here

It was working fine until I added componentDidUpdate in AddPost.js and also in handleSubmit when I m trying to display props on my console ,its display a warning says Cannot read property 'posts' of undefined (this is before I have added componentDidUpdate )

Here is AddPost.js :-

import React from 'react';
import {connect} from 'react-redux';
import {withStyles} from '@material-ui/core/styles';
import * as AdminActions from '../../../store/actions/adminActions';
import Paper from '@material-ui/core/Paper';
import {withFormik ,Form} from "formik";
import {FormikTextField, FormikSelectField} from 'formik-material-fields';
import Button from '@material-ui/core/Button';
import SaveIcon from '@material-ui/icons/Save';
import {withRouter} from 'react-router-dom';

import * as Yup from 'yup';


const styles = theme =>({
    container:{
        margin : theme.spacing.unit *3,
        display: 'flex',
        flexDirection: 'row wrap',
        width: '100%' 
    },
    formContol:{
        margin: theme.spacing.unit
    },
    leftSide:{
        flex:4,
        height: '100%',
        margin: theme.spacing.unit * 1,
        padding: theme.spacing.unit * 3
    },
    rightSide:{
        flex: 1,
        height: '100%',
        margin: theme.spacing.unit * 1,
        padding: theme.spacing.unit * 3

    }

});

class AddPost extends React.Component{
    componentDidUpdate(props,state){
        if(this.props.match.params.view === 'add' && this.props.admin.posts.filter(p=> p.title === this.props.values.title).length >0){
            const post = this.props.admin.posts.filter(p => p.title === this.props.values.title)[0];
            this.props.history.push('/admin/posts/edit/' + post.dispatch);
        }
    }
    render(){
        const {classes}= this.props;

        return(
            <div >
         
            <Form className={classes.container}>
            <Paper className={classes.leftSide}>
                    <FormikTextField

                    name="title"
                    label="Title"
                    margin="normal"
                    onChange={e=> this.props.setFieldValue('slug',e.target.value.toLowerCase().replace(/ /g,'_'))}
                    fullWidth
                    />      
                    <FormikTextField
                    name="slug"
                    label="Slug"
                    margin="normal"
                
                    />     
                    <FormikTextField
                    name="content"
                    label="Content"
                    margin="normal"
                    fullWidth
                    />
                </Paper>
                <Paper className={classes.rightSide}>
                    <FormikSelectField
                        name="status"
                        label="Status"
                        margin="normal"
                        options={[
                            {label:'Unpublished',value:false},
                            {label:'Published',value:true}
                        ]}
                        fullWidth
                    />
                    <Button 
                    variant="contained" 
                    color="secondary"
                    onClick={e =>{
                        this.props.handleSubmit();
                    }}
                    ><SaveIcon /> Save</Button>

                </Paper>           
            </Form>
        </div>
        )
    }
}

const mapStateToProps = state =>({
    auth: state.auth,
    auth: state.admin
});

const mapDispatchToProps = dispatch =>({
    addPost: (post, token) =>{
        dispatch(AdminActions.addPost(post,token));
    }
});

export default withRouter(connect(
    mapStateToProps,
    mapDispatchToProps
)(withFormik({
    mapPropsToValues: () => ({
        title:'',
        slug:'',
        createdAt:'',
        status:false,
    }),
    validationSchema: Yup.object().shape({
        title:Yup.string().required('Title is required'),
        slug: Yup.string().required(),
        content: Yup.string().required()
    }),
    handleSubmit:(values ,{setSibmitting,props})=>{
        console.log("saving", props.addPost);
        props.addPost(values , props.auth.token);
    }
})(withStyles(styles)(AddPost))));

here is adminActions.js:-

import API from '../../utils/api';

export const getUsers=(token) =>{
    return dispatch =>{
        API.getUsers(token,res =>{
        
            dispatch({
                type:'GOT USERS',
                payload:res.data
            })
        })
    }

}

export const getPosts =(token)=>{
    return dispatch =>{
        API.getPosts(token,res =>{
            dispatch({
                type:'GOT_POSTS',
                payload: res.data
            })
        })
    }
}

export const addPost=(post,token) =>{
    return dispatch=>{
        API.addPost(post,token, res => {
            dispatch({

                type:'POST_ADDED',
                payload: res.data
            })
        })
    }
}

here is adminReducers.js:-

const defaultState={
    users:[],
    posts:[]
}

const admin=(state = defaultState,action)=>{
    switch(action.type){
        case 'GOT USERS':
            return{
                ...state,
                users: action.payload
            }
            case 'GOT_POSTS':
                return {
                    ...state,
                    posts: action.payload
                }
            case 'POST_ADDED':
                return{
                    ...state,
                    posts: state.posts.concat(action.payload)
                }
            default:
                return state
    }
}

export default admin;

here is api.js:-

import axios from 'axios';

const host= 'http://localhost:8080';
const API={

 login:  (email,pass,success)=>{
     axios.post(`${host}/api/users/login`,{email:email , password:pass})
     .then(res =>{success(res);
    });

 },
  getUsers:(token,success) =>{
      axios.get(`${host}/api/users?access_token=${token}`)
      .then(res =>{
          success(res);
      })
  },
  getPosts:(token,success)=>{
      axios.get(`${host}/api/POSTs?access_token=${token}`)
      .then( res=>{
          success(res);
      })
  },
  addPost: (post ,token, success) =>{
      axios.post(`${host}POSTs?access_token=${token}`, post)
      .then( res =>{
          success(res);
      });
  }

}

export default API;

here is App.js:-

import React from 'react';
import PageWrapper from "./components/PageWrapper";
import {BrowserRouter as Router,Route} from 'react-router-dom';
import {connect} from 'react-redux';

//PAGES
import Home from "./components/Pages/Home.js";
import About from "./components/Pages/About.js";
import Contact from "./components/Pages/Contact.js";
import Login from "./components/Pages/Login.js";

//Admin pages
import Dashboard from './components/Pages/Admin/Dashboard';
import Users from './components/Pages/Admin/Users';
import Posts from './components/Pages/Admin/Posts';
import AddPost from './components/Pages/Admin/AddPost';

import AdminWrapper from "./components/AdminWrapper.js"
import LoginWrapper from "./components/LoginWrapper.js";


class App extends React.Component{
  render(){
  return (
    <div>
    
    <Router>
<Route 
path='/admin/users'
render={props =>{
  return(
  <div>
      {this.props.auth.token ?
        <AdminWrapper>
      <Users/>
      </AdminWrapper>
        : 
        <LoginWrapper>
           <Login/>
        </LoginWrapper>
       
      }
        
      </div>     
)}
  }

 />
<Route
  path='/admin/posts/:view'
  exact={true}
  render={props=>{
    return(
      <div>
      {this.props.auth.token ?
        <AdminWrapper>
      < AddPost />
      </AdminWrapper>
        : 
        <LoginWrapper>
           <Login/>
        </LoginWrapper>
       
      }
        
      </div> 

    )
  }}
/>



<Route 
path='/admin/posts'
exact={true}
render={props =>{
  return(
  <div>
      {this.props.auth.token ?
        <AdminWrapper>
      <Posts />
      </AdminWrapper>
        : 
        <LoginWrapper>
           <Login/>
        </LoginWrapper>
       
      }
        
      </div>     
)}
  }

/>



      <Route
      exact={true}
      path='/admin'
      render={props =>{
        return(
        <div>
            {this.props.auth.token ?
              <AdminWrapper>
            <Dashboard/>
            </AdminWrapper>
              : 
              <LoginWrapper>
                 <Login/>
              </LoginWrapper>
             
            }
              
            </div>     
      )}
        }
      
      />
    
    
          
            <Route exact={true} path="/"
            render={props =>(
              <PageWrapper>
                <Home {...props} />
              </PageWrapper>
            )}
            ></Route>

            <Route
            path="/about"
            render={props =>(
              <PageWrapper>
                <About {...props} />
              </PageWrapper>
            )}
            />
            <Route
            path="/contact"
            render={props =>(
              <PageWrapper>
                <Contact {...props} />
              </PageWrapper>
            )}
            />
            
      
      </Router>
      </div>
  );
}
}

const mapStateToProps=state=>{
  return{
    auth:state.auth
  }
}

const mapDispatchToProps = dispatch =>{
  return{

  }
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(App);

Please help me out to solve this 🙂

Answer

You are defining auth twice.

const mapStateToProps = state =>({
  auth: state.auth,
   auth: state.admin
});

should be:

const mapStateToProps = state =>({
  auth: state.auth,
  admin: state.admin
});