简体   繁体   English

React.createElement:类型无效(redux / react-router?)

[英]React.createElement: type is invalid (redux/react-router?)

I realise this question has been asked quite a few times: 我知道这个问题已经问了很多遍了:

...but none of these have helped me. ...但是这些都没有帮助我。 I get from these questions/answers that the general consensus is that this commonly happens with an import / export issue which (looking through my code base, is not the issue I have) . 从这些问题/答案中,我得出的普遍共识是,这通常发生在import / export问题中(通过我的代码库查看,这不是我遇到的问题)

I have 3 components: CognitoLogin , ListGroups and InviteUserModal . 我有3个组件: CognitoLoginListGroupsInviteUserModal CogntioLogin is an auth service and redirects to ListGroups using react-router-dom <Redirect> . CogntioLogin是一项身份验证服务,并使用react-router-dom <Redirect>重定向到ListGroups This then renders InviteUserModal on the click of a button. 然后,单击按钮即可呈现InviteUserModal This is my code (the bits that matter) : 这是我的代码(重要的一点)

CognitoLogin.js CognitoLogin.js

render() {
    const { redirect } = this.state;

    if (redirect) {
        return <Redirect to={{
            pathname: redirect,
            state: {
                email: this.state.email
            }
        }}/>;
    }

    return (
        <div id="dialog-region">
            <div className="login-view">
                { !this.props.location.state.loginAuth &&
                    <CognitoMessage email={this.state.email}/>
                }
                <div id="login-logo">
                    <Image id="pimberly-logo" src={PimberlyLogo} responsive/>
                    <Image id="cognito-logo" src={CognitoLogo} responsive/>
                </div>
                <LoginForm handleLogin={this.handleLogin}/>
                <div className="checkbox forgottenReset">
                    <a id="reset-password" onClick={this.handlePasswordReset}>Forgotten password?</a>
                </div>
                <div className="checkbox forgottenReset">
                    <a id="resend-confirm" onClick={this.handleResend} href="#">Resend confirmation</a>
                </div>
                { this.state.err &&
                    <ErrorAlert err={this.state.err} />
                }
                { this.state.apiRes &&
                    <SuccessAlert res={this.state.apiRes} />
                }
                { this.state.resend &&
                    <InfoAlert email={this.state.email}/>
                }
            </div>
        </div>
    );
}

ListGroups.js ListGroups.js

import React, { Component } from "react";
import axios from "axios";
import { connect } from "react-redux";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Table, ButtonToolbar, Button } from "react-bootstrap";

// Selectors
import { getUser } from "../selectors/user";
import { getGroupByName } from "../selectors/group";

// Actions
import { setUsersGroupsPersist } from "../actions/user";

// Components
import ErrorAlert from "./ErrorAlert";
import ListUsersModal from "./ListUsersModal";
import InviteUsersModal from "./InviteUsersModal";

// Styles
import "../../css/login.css";

class ListGroups extends Component {
    constructor(props) {
        super(props);

        this.state = {
            groups: [],
            showModal: false,
            groupName: "",
            emailOfUser: props.location.state.email
        };

        this.handleRemoveInviteUsers = this.handleRemoveInviteUsers.bind(this);
        this.closeModal = this.closeModal.bind(this);

        this.props.setUsersGroupsPersist(this.state.emailOfUser);
    }

    handleRemoveInviteUsers(event) {
        const groupSelected = this.props.groups.find((group) => {
            return (group.name === event.currentTarget.dataset.groupName);
        });

        event.preventDefault();

        this.setState({
            groupAction: event.currentTarget.dataset.groupAction
        });

        return axios.post(`http://${process.env.BASE_API}/groups/users/list`, {
            groupName: groupSelected.name
        })
            .then((res) => {
                this.setState({
                    showModal: true,
                    users: res.data.Users
                });
            })
            .catch((err) => {
                this.setState({
                   apiErr: err
                });
            });
    }

    closeModal(event) {
        this.setState({
            showModal: false
        });
    }

    render() {
        const Modal = (this.state.groupAction === "remove") ? <ListUsersModal /> : <InviteUsersModal />;

        return (
            <>
                <div id="dialog-region">
                    <Table striped bordered condensed hover>
                        <thead>
                            <tr>
                                <th scope="col" className="col-name">Name</th>
                                <th scope="col" className="col-description">Description</th>
                                <th scope="col" className="col-created">Created</th>
                                <th scope="col" className="col-buttons"></th>
                            </tr>
                        </thead>
                        <tbody>
                            { this.props.groups.map(function(group, i) {
                                return <tr key={i}>
                                    <td>{ group.name }</td>
                                    <td>{ group.description }</td>
                                    <td>{ group.created }</td>
                                    <td>
                                        <ButtonToolbar>
                                            <Button bsStyle="primary" onClick={this.handleRemoveInviteUsers} data-group-name={group.name} data-group-action="invite">
                                                <FontAwesomeIcon icon="plus"/> Invite users
                                            </Button>
                                            <Button bsStyle="danger" onClick={this.handleRemoveInviteUsers} data-group-name={group.name} data-group-action="remove">
                                                <FontAwesomeIcon icon="trash"/> Remove users
                                            </Button>
                                        </ButtonToolbar>
                                    </td>
                                </tr>;
                            }, this)}
                        </tbody>
                    </Table>
                    { this.state.showModal &&
                        <Modal closeModal={this.closeModal}/>
                    }
                    { this.state.apiErr &&
                        <ErrorAlert err={this.state.apiErr} />
                    }
                </div>
            </>
        );
    }
}

const mapStateToProps = (state, props) => {
    const user = getUser(state, props.location.state.email);
    const groups = user.groups.map((groupName) => {
        return getGroupByName(state, groupName);
    });

    return {
        user,
        groups
    };
};

export default connect(
    mapStateToProps,
    { setUsersGroupsPersist }
)(ListGroups);

InviteUsersModal.js InviteUsersModal.js

import React, { Component } from "react";
import axios from "axios";
import { connect } from "react-redux";
import { Modal, Button, FormGroup, FormControl, ControlLabel, Table } from "react-bootstrap";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";

import ErrorAlert from "./ErrorAlert";

export default class InviteUsersModal extends Component {
    constructor(props) {
        super(props);

        this.state = {
            currentEmail: "",
            emailsToInvite: []
        };

        this.handleInviteUser = this.handleInviteUser.bind(this);
        this.handleEmailChange = this.handleEmailChange.bind(this);
    }

    handleInviteUsers(event) {
        event.preventDefault();

        return axios.post(`http://${process.env.BASE_API}/groups/users/invite`, {
            emails: this.state.emailsToInvite,
            emailOfInviter: this.props.emailOfUser,
            groupName: this.props.groupName
        })
            .then((res) => {
                this.props.closeModal();
            })
            .catch((err)=> {
                this.setState({
                    apiErr: err
                });
            });
    }

    handleSubmit(event) {
        this.setState({
            emailsToInvite: [...this.state.emailsToInvite, this.state.currentEmail]
        });
    }

    handleRemoveInvite(event) {
        const emailToRemove = event.currentTarget.dataset.email;

        event.preventDefault();

        this.state.emailsToInvite.splice(this.state.emailsToInvite.indexOf(emailToRemove), 1);
    }

    handleEmailChange(event) {
        this.setState({
            currentEmail: event.currentTarget.value
        });
    }

    handleModalClose() {
        this.props.closeModal();
    }

    render() {
        return (
            <Modal show={this.props.showModal} onHide={this.handleModalClose} bsSize="large">
                <Modal.Header closeButton>
                    <Modal.Title>Invite</Modal.Title>
                </Modal.Header>

                <Modal.Body>
                    <form role="form" onSubmit={this.handleSubmit}>
                        <FormGroup controlId="inviteUsersForm">
                            <FormControl type="email" value={this.state.currentEmail} placeholder="Email" onChange={this.handleEmailChange}></FormControl>
                            <Button type="submit" bsStyle="primary">
                                <FontAwesomeIcon icon="plus"/> Invite
                            </Button>
                        </FormGroup>
                    </form>
                    <hr/>
                    <h1>Users to invite</h1>
                    <Table striped bordered condensed hover>
                        <thead>
                            <tr>
                                <th scope="col">Email</th>
                                <th scope="col"></th>
                            </tr>
                        </thead>
                        <tbody>
                            { this.state.emailsToInvite.map(function(email, i) {
                                return <tr key={i}>
                                    <td>{ email }</td>
                                    <td>
                                        <Button bsStyle="danger" onClick={this.handleRemoveInvite} data-email={email}>
                                            <FontAwesomeIcon icon="minus"/>
                                        </Button>
                                    </td>
                                </tr>;
                            }, this)}
                        </tbody>
                    </Table>
                    { this.state.apiErr &&
                        <ErrorAlert err={this.state.apiErr}/>
                    }
                </Modal.Body>

                <Modal.Footer>
                    <Button onClick={this.handleModalClose}>Cancel</Button>
                    <Button onClick={this.handleInviteUsers} bsStype="primary">Save</Button>
                </Modal.Footer>
            </Modal>
        );
    }
}

As it looks, I am importing the component correctly. 从外观上看,我正在正确导入组件。 When debugging, the constructor is not even hit so am unsure where it is going wrong. 调试时, constructor甚至都没有被击中,因此不确定它出了什么问题。

This did work before I introduced react-router/redux so is is possible they are the problem? 在我引入react-router / redux之前这确实起作用了,所以可能是问题所在吗?

The error(s) happen when I click on the button to "Invite users" . 当我单击“邀请用户”按钮时,就会发生错误。 When debugging, I can get to the line to show the modal and any further than that will throw an error. 进行调试时,我可以显示该模式,并且超出此范围将引发错误。

The full list of errors are: 错误的完整列表是:

错误

EDIT 编辑

I have also tried rendering the InviteUsersModal via element variables instead so the render method would be: 我还尝试过通过元素变量呈现InviteUsersModal ,因此render方法将是:

render() { const Modal = (this.state.groupAction === "remove") ? render(){const Modal =(this.state.groupAction ===“删除”)? : ; :;

    return (
        <>
            <div id="dialog-region">
                <Table striped bordered condensed hover>
                    ...
                </Table>
                { this.state.showModal &&
                    {Modal}
                }
                ...
            </div>
        </>
    );
}

but get similar errors: 但得到类似的错误:

在此处输入图片说明

I think you should adjust the following line: 我认为您应该调整以下行:

const Modal = (this.state.groupAction === "remove") ? <ListUsersModal /> : <InviteUsersModal />;

To: 至:

const Modal = (this.state.groupAction === "remove") ? ListUsersModal : InviteUsersModal;

You are assigning an instance of the component to variable Modal and instead of rendering it you are using it as Component 您正在将组件实例分配给变量Modal,而不是渲染它,而是将其用作组件

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM