[英]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个组件: CognitoLogin , ListGroups和InviteUserModal 。 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.