0
votes

Error Message:

https://imgur.com/LBNyl2M

App.js

import React, { Component } from 'react';
import { StyleSheet } from 'react-native';
import { Provider } from 'react-redux';
import Layout from './containers/Layout/Layout';

import store from './store/index';

export default function App() {

    return (

      <Provider store={store}><Layout/></Provider>

    );

}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

index.js

import { createStore } from 'redux';
import reducer from './reducer';

const store = createStore(reducer);

export default store;

reducer.js

import * as actionTypes from './actions';
import moment from 'moment';

const initialState = {

    itemList: [],
    idCount: 0,
    text: 'Write your to do item!',
    chosenDate: 'no-date',
    activeItems: 0,
    completedItems: 0,
    showCompletedList: false

}

const reducer = (state = initialState, action) => {

    switch(action.type){

        case actionTypes.ADDTOLIST:

            const objItem = { 'id': state.idCount+1, 'text': state.text, 'date': state.chosenDate, 'completed': false, 'displayTextInput': false, 'pickerVisible': false };
            return {
                ...state, 
                itemList: [...state.itemList, objItem],
                idCount: state.idCount+1,
                activeItems: state.activeItems+1
            }

        case actionTypes.REMOVEFROMLIST:

            let oldItemList = [...state.itemList];
            let index = oldItemList.indexOf(action.item);

            if( index !== -1) oldItemList.splice(index, 1);

            return {
                ...state,
                itemList: [...oldItemList],
                activeItems: action.item.completed ?  state.activeItems : state.activeItems-1,
                completedItems: action.item.completed ?  state.completedItems-1 : state.completedItems
            }

        case actionTypes.EDITITEMDATE:

            oldItemList = [...state.itemList];
            index = oldItemList.indexOf(action.item);

            if(index !== -1){
                oldItemList[index].date = state.chosenDate;
                return {
                    ...state,
                    itemList: [...oldItemList]
                }
            }

            return state;

        case actionTypes.EDITITEMSTATUS:

            oldItemList = [...state.itemList];
            index = oldItemList.indexOf(action.item);

            if(index !== -1){
                oldItemList[index].completed = !oldItemList[index].completed;
                return {
                    ...state,
                    itemList: [...oldItemList],
                    activeItems: action.item.completed ?  state.activeItems+1 : state.activeItems-1,
                    completedItems: action.item.completed ?  state.completedItems-1 : state.completedItems+1
                }
            }

            return state;

        case actionTypes.EDITITEMTEXT:

            oldItemList = [...state.itemList];
            index = oldItemList.indexOf(action.item);

            if(index !== -1){
                oldItemList[index] = state.text;
                return {
                    ...state,
                    itemList: [...oldItemList]
                }
            }

            return state;

        case actionTypes.TOGGLETEXTINPUT:

            oldItemList = [...oldItemList];
            index = oldItemList[index].indexOf(action.item);

            if(index !== -1){
                oldItemList[index],displayTextInput = !oldItemList[index],displayTextInput;
                return {
                    ...state,
                    itemList: [...oldItemList]
                }
            }

            return state;

        case actionTypes.FILTERACTIVEITEMS:
            return {
                ...state,
                showCompletedList: false
            }

        case actionTypes.FILTERCOMPLETEDITEMS:
            return {
                ...state,
                showCompletedList: true
            }

        case actionTypes.HANDLECHANGETEXT:
            return {
                ...state,
                text: action.text
            }

        case actionTypes.HIDEPICKERINITEM:

            oldItemList = [...state.itemList];
            index = oldItemList[index].indexOf(item);

            if(index !== -1){
                oldItemList[index].isVisible = false;
                return {
                    ...state,
                    itemList: [...oldItemList]
                }
            }

        case actionTypes.SHOWPICKERINITEM:

                oldItemList = [...state.itemList];
                index = oldItemList[index].indexOf(item);

                if(index !== -1){
                    oldItemList[index].isVisible = true;
                    return {
                        ...state,
                        itemList: [...oldItemList]
                    }
                }

                return state;

        case actionTypes.HANDLEPICKER:

            return{
                ...state,
                chosenDate: moment(action.datetime).format('MMM, Do YYYY HH:mm') 
            }

    }

}

export default reducer;

Layout.js

import React, { Component } from 'react';
import { Button, KeyboardAvoidingView } from 'react-native';
import AddScreen from '../../components/AddScreen/AddScreen';
import TodoList from '../../components/TodoList/TodoList';
import Header from '../../components/UI/Header/Header';

class Layout extends Component {

    state = {

        displayItems: false,
        pickerVisible: false

    }

    toggleItems = () => {
        this.setState({ displayItems: !this.state.displayItems });
    }

    showPicker = () => {
        this.setState({ pickerVisible: true });
    }

    hidePicker = () => {
        this.setState({ pickerVisible: false });
    }

    render () {

        let childComponent = <AddScreen 
                                toggleItems={this.props.toggleItems}
                                showPicker={this.props.showPicker}
                                hidePicker={this.props.hidePicker}
                                pickerVisible={this.props.pickerVisible}

                                />;

        if(this.props.displayItems){

            childComponent = <TodoList 
                                itemList={this.state.itemList} 
                                showCompletedList={this.state.showCompletedList}

                                />;

        }

        return (
           <KeyboardAvoidingView style={{flex:1}} behavior="padding">

                <Header />

                {childComponent}

                <Button title='Toggle Items' onPress={this.toggleItems} /> 

           </KeyboardAvoidingView>
        );
    }

}

export default Layout;

my complete project on github: https://github.com/rvmelo/todolist-redux

Is it an error in the code or is it related to some package update?

I get the following error: "Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports."

1
Can you provide your reducer file? - sanjar
Yes I already did - user8955046
The error says check render method of Layout. Please post your Layout component. The error will most likely be there. - Brian Thompson
Already posted my Layout.js component - user8955046
Can you check if you have export statement in Header component and you are returning JSX? - iRohitBhatia

1 Answers

0
votes

You're going to have to do some tracing down on your end. That error typically comes when you try to render a component that doesn't exist (or doesn't exist at the path you've told it it does), which is impossible to tell without having access to most of the project.

In AddScreen, TodoList, and Header make sure they all export default. And if they render any outside components you will need to check the same for them if imported the same way.

One way to debug this would be to remove each component one at a time and see which one makes it break.

-------UPDATE---------

Looking at your project on GitHub, I see that two of the components are named exports.

Change Layout to the following:

import { AddScreen } from '../../components/AddScreen/AddScreen';
import { TodoList } from '../../components/TodoList/TodoList';

Explanation

When you do export myFunction, its a named export. So you must import it with the named import syntax like this:

import { myFunction } from '..'

When you do export default myFunction, its a default export and can be imported as anything, so you don't use the curly braces and instead do this:

import Anything from '...' //path to myFunction