1

I have a problem rendering a component with react. I'm trying to code a wizard, however I get the following error when rendering Mstep1.

Element type is invalid: expected a string (for built-in components) or a hereclass/function (for composite components) but got: object. You herelikely forgot to export your component from the file it's defined in.

To better explain, here is some code:

-- wizard.js --

import React, { Component } from 'react';

import { Mstep1, Mstep2 } from './Steps'
import { states } from './States'
import { StateMachine } from './StateMachine.js';

class Wizard extends Component {
    constructor(props) {
        super(props);
        this.state = {
            currentState: states.MSTEP1,
            formSaves: [],

        }

        this.saveForm =this.saveForm.bind(this);
        this.nextStep = this.nextStep.bind(this);
        this.backStep = this.backStep.bind(this);
        this.stateMachine = new StateMachine();
    }

    saveForm(formSave) {
        let formSaves = this.state.formSaves.concat();
        formSaves.push(formSave);
        this.setState({
            formSaves: formSaves
        });
    }

    nextStep(desiredState) {
        let currentState = this.state.currentState;
        let nextState = this.stateMachine.transitionTo(currentState, desiredState);
        this.setState({
            currentState: nextState
        });
    }

    backStep(desiredState) {
        let currentState = this.state.currentState;
        this.setState({
            currentState: this.stateMachine.transitionFrom(currentState, desiredState)
        });
    }

    //Switch Case Methode um den CurrentStep zu bestimmen
    currentStep() {
        console.log(this.state.currentState);
        // console.log(typeof this.state.currentState);
        switch (this.state.currentState) {
            case states.MSTEP1:
            console.log(typeof states.MSTEP1);
                return <Mstep1
                    saveForm={this.save}
                    back={this.backStep}
                    next={this.nextStep}
                />;
                break;
            case states.MSTEP2:
                return(<Mstep2
                />);                     

            default:
                break;
        }


    }

    render() {

        return (

            <div>
                {this.currentStep()}
            </div>
        );
    }
}
export default Wizard;

--Steps.js---

import React, { Component } from 'react';
import { states } from './States.js';


import TextArea from './Select';
import SingleInput from './SingleInput';

// import Select from './Select';



export class Mstep1 extends Component {
    constructor(props) {    
        super(props);
        this.state = {
            modultitel: '',
            startdate: '',
            enddate: '',
            modulkuerzel: '',
            modulDescription: ''
        };

        //Bindings 

        this.handleModultitel = this.handleModultitel.bind(this);
        this.handleStartdate = this.handleStartdate.bind(this);
        this.handleEnddate = this.handleEnddate.bind(this);
        this.handleModulkuerzel = this.handleModulkuerzel.bind(this);
        this.handlemodulDescriptionChange = this.handlemodulDescriptionChange.bind(this);
        this.validate = this.validate.bind(this);
    }
    handleModultitel(e) {
        this.setState({ modultitel: e.target.value }, () => console.log('modultitel:', this.state.modultitel));
    }

    handleStartdate(e) {
        this.setState({ startdate: e.target.value }, () => console.log('startdate:', this.state.startdate));
    }

    handleEnddate(e) {
        this.setState({ enddate: e.target.value }, () => console.log('enddate:', this.state.enddate));
    }

    handleModulkuerzel(e) {
        this.setState({ modulkuerzel: e.target.value }, () => console.log('modulkuerzel', this.state.modulkuerzel));
    }

    handlemodulDescriptionChange(e) {
        // const textArray = e.target.value.split('').filter(x => x !== 'e');
        // console.log('string split into array of letters',textArray);
        // const filteredText = textArray.join('');
        // this.setState({ modulDescription: filteredText }, () => console.log('modulDescription', this.state.modulDescription));
        this.setState({ modulDescription: e.target.value }, () => console.log('modulDescription', this.state.modulDescription));
    }

    handleClearForm(e) {
        e.preventDefault();
        this.setState({
            modultitel: '',
            startdate: '',
            enddate: '',
            modulkuerzel: '',
            modulDescription: ''
        });
    }

    validate(e) {
        e.preventDefault();

       this.props.saveForm({
            modultitel: '',
            startdate: '',
            enddate: '',
            modulkuerzel: '',
            modulDescription: '',
        });
        this.props.next(this.props.nextState);


        this.handleClearForm(e);
    }

    render() {
        return (
            <form>
                <h5>Modul anlegen (Schritt 1 von x)</h5>
                <SingleInput
                    inputType={'text'}
                    title={'Modultitel: '}
                    name={'name'}
                    controlFunc={this.handleModultitel}
                    content={this.state.modultitel}
                    placeholder={'Modultitel'} />
                <SingleInput
                    inputType={'text'}
                    title={'Gültig ab: '}
                    name={'Startdate'}
                    controlFunc={this.handleStartdate}
                    content={this.state.startdate}
                    placeholder={'Startdatum'} />
                <SingleInput
                    inputType={'text'}
                    title={'Gültig bis: '}
                    name={'Enddate'}
                    controlFunc={this.handleEnddate}
                    content={this.state.enddate}
                    placeholder={'Enddatum'} />
                <SingleInput
                    inputType={'text'}
                    title={'Modulkürzel'}
                    name={'Modulkürzel'}
                    controlFunc={this.handleModulkuerzel}
                    content={this.state.modulkuerzel}
                    placeholder={'Modulkützel'} />
                <TextArea
                    title={'Kurzbeschreibung'}
                    rows={5}
                    name={'Kurzbeschreibung'}
                    resize={false}
                    content={this.state.modulDescription}
                    controlFunc={this.handlemodulDescriptionChange}
                    placeholder={'Kurzbeschreibung zu Modulen'} />
                <button
                    onClick={this.validate}>Weiter</button>
                <button
                    onClick={this.handleClearForm}>Clear form</button>
            </form>
        );
    }
}// Ende Class Mstep1


export class Mstep2 extends Component {
    constructor(props) {
        super(props);
        this.state = {
            modulThema: '',
            themaDescription: ''
        };
        this.handleFormSubmit = this.handleFormSubmit.bind(this);
        this.handleThemaDescription = this.handleThemaDescription.bind(this);
        this.back = this.back.bind(this);
    }

    handleModulthema(e) {
        this.setState({ modulThema: e.target.value }, () => console.log('thema: ', this.state.modulThema));
    }

    handleThemaDescription(e) {
        this.setState({ themaDescription: e.target.value }, () => console.log('tDescription', this.state.themaDescription))
    }

    back(e) {
        e.preventDefault();
        this.props.back(states.MSTEP1);
    }


    validate(e) {
        e.preventDefault();

        this.props.saveForm({
            modulThema: '',
            themaDescription: ''
        });
        this.props.next(this.props.nextState);

        this.handleClearForm(e);
    }



    render() {

        return (
            <form>
                <h5>Modul anlegen (Schritt 2 von x)</h5>
                <SingleInput
                    inputType={'text'}
                    title={'Neues Thema'}
                    name={'modulname'}
                    controlFunc={this.handleModulThema}
                    content={this.modulThema}
                    placeholder={'Modulthema'} />
                <TextArea
                    title={'Beschreibung (Inhalte des Thmas)'}
                    rows={5}
                    name={'Thema-Beschreibung'}
                    resize={10}
                    controlFunc={this.handleThemaDescription}
                    content={this.state.themaDescription}
                    placeholder={''} />
                <button
                    onClick={this.validate}>Weiter</button>
                    <button
                    onClick={this.back}>zurück</button>
                <button
                    onClick={this.handleClearForm}>Clear form</button>
            </form>
        );
    }
}

3
  • Can you show States file? Commented Nov 9, 2017 at 11:52
  • Her is the Code: import keyMirror from 'keymirror'; export const states = keyMirror({ MSTEP1: true, MSTEP2: true, }); Commented Nov 9, 2017 at 11:57
  • 1
    import TextArea from './Select'; looks very suspicious - isn't the file name wrong? Commented Nov 9, 2017 at 12:04

2 Answers 2

1

I would recommend you to split Mstep1 and Mstep2 into two different files and then you can export default class Mstep1 for example and import with import Mstep1 from 'Steps/Mstep1'. It's a good practice in React that you stick to one component per file. Refer to this article as a good reference to organize your react applications.

Sign up to request clarification or add additional context in comments.

Comments

0

You can do export const class Mstep1 and export const Mstep2. So that you can import it like you already have.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.