0
votes

I am trying to make own components for modal. First component is modal and second component is title. When I added this line <MyModal.MyModalTitle property='My header'/> in App.js a I got the error in console:

react.development.js?72d0:207 Warning: React.createElement: 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.

Blockquote Check the render method of App. in App (created by Route) in Route (created by RouterMapping) in Switch (created by RouterMapping) in Router (created by BrowserRouter) in BrowserRouter (created by RouterMapping) in RouterMapping

Thank you for help.

My source is: App.js

import React from 'react';
import logo from '../images/logo.svg';
import {BootstrapTable, TableHeaderColumn} from 'react-bootstrap-table';
import {Button} from 'react-bootstrap';
import MyAlert from './render/component/alert/MyAlert';
import MyModal from './render/component/modal/MyModal';
import {hidingAlertAfterTime} from './render/index.jsx';

class App extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            beers: [],
            visibleAlert: false,
            visibleModal: false
        };

        this.onDismissAlert = this.onDismissAlert.bind(this);
        this.onDismissModal = this.onDismissModal.bind(this);
    }

    onDismissAlert() {
        this.setState({visibleAlert: false});
    }

    onDismissModal() {
        this.setState({visibleModal: false});
    }

    componentDidMount() {
        this.loadBeersFromServer();
    }

    loadBeersFromServer() {
        fetch('http://localhost:8084/api/good-beers', {
            method: 'GET'
        })
            .then((response) => response.json())
            .then((beers) => {
                this.setState({
                    beers: beers
                });
            });
    };

    editItem(row) {
        console.log('Product #', row.id);
        this.setState({visibleModal: true});
    }

    deleteItem(row) {
        const id = row.id;
        fetch('http://localhost:8084/api/good-beers/' + id,
            {method: 'GET'})
            .then(
                () => {
                    this.loadBeersFromServer();
                    this.setState({
                        visibleAlert: true,
                        alertText: 'Záznam "' + row.name + '" byl úspěšně smazán.',
                        alertColor: 'success',
                    }, hidingAlertAfterTime)
                }
            )
            .catch(() => {
                this.setState({
                    visibleAlert: true,
                    alertText: 'Záznam "' + row.name + '" se nepodařilo odstranit.',
                    alertColor: 'danger',
                }, hidingAlertAfterTime)
            });
    }

    cellButton(cell, row) {
        return (
            <div>
                <Button
                    type="button" bsStyle="primary"
                    onClick={() =>
                        this.editItem(row)}>Edit</Button>
                <Button
                    type="button" bsStyle="danger"
                    onClick={() =>
                        this.deleteItem(row)}>Delete</Button>
            </div>
       )
    }

render() {
    return (
        <div className="App">
            <header className="App-header">
                <img src={logo} className="App-logo" alt="logo"/>
                <h1 className="App-title">Wellcome to React</h1>
            </header>

            <MyAlert open={this.state.visibleAlert} toggle={this.onDismissAlert}
                     alert={{color: this.state.alertColor, text: this.state.alertText}}/>

            <MyModal show={this.state.visibleModal} onHide={this.onDismissModal}>
                <MyModal.MyModalTitle property='My header'/>
            </MyModal>

            <BootstrapTable data={this.state.beers} options={{noDataText: 'Zatím nebyl vložen žádný záznam'}}
                            version='4' striped={true} hover={true}>
                <TableHeaderColumn dataField='id' isKey={true} dataSort width='20%'>ID</TableHeaderColumn>
                <TableHeaderColumn dataField='name' dataSort>Pivo</TableHeaderColumn>
                <TableHeaderColumn dataField='button' dataFormat={this.cellButton.bind(this)} width='10%'/>
            </BootstrapTable>

            </div>
        );
    }
}
export default App;

MyModal.jsx

import React from 'react';
import {Button, Modal} from 'react-bootstrap';
import MyModalTitle from './MyModalTitle';

class MyModal extends React.Component {
    render() {
        return <Modal
            show={this.props.show}
            onHide={this.props.onHide}
            animation={false}
        >
           <Modal.Header style={{display: 'block'}} closeButton >
                <MyModalTitle property={this.props.children} />
           </Modal.Header>
           <Modal.Body>
                <h4>Text in a modal</h4>
                <p>
                    Duis mollis, est non commodo luctus, nisi erat porttitor ligula.
                </p>
            </Modal.Body>
            <Modal.Footer>
                <Button onClick={this.props.onHide}>Zavřít</Button>
            </Modal.Footer>
        </Modal>
    }
}
export default MyModal;

MyModalTitle.jsx

import React from 'react';
import {Modal} from 'react-bootstrap';

class MyModalTitle extends React.Component {
    render() {
        const modal = this.props.property;
        return (
            <Modal.Title>{modal.props.property}</Modal.Title>
        )
    }
}
export default MyModalTitle;
1
Import MyModal directly. - elken
@elken sorry I don't understand your's response. How import MyModal directly? - user3468921
import MyModalTitle from './render/component/modal/MyModalTitle'; in App.js - elken

1 Answers

1
votes

MyModal.MyModalTitle isn't defined (you would need to export MyModalTitle from MyModal in order for that syntax to work). In App.js you need to add import MyModalTitle from './render/component/modal/MyModalTitle'; and then use

           <MyModalTitle property='My header'/>

instead of

           <MyModal.MyModalTitle property='My header'/>

within App.js.