我已经构建了一个Rails 6应用程序,该应用程序使用React作为前端,并使用Bootstrap React作为样式组件。本地一切正常,但是当我部署到Heroku并尝试创建“中断”时,会引发以下错误:
Modal.js:21 Uncaught TypeError: Cannot convert undefined or null to object
at hasOwnProperty (<anonymous>)
at Modal.js:21
at Array.forEach (<anonymous>)
at Modal.js:20
at t.n.render (Modal.js:302)
at Qi (react-dom.production.min.js:4243)
at Ji (react-dom.production.min.js:4234)
at wc (react-dom.production.min.js:6676)
at yu (react-dom.production.min.js:5650)
at Mu (react-dom.production.min.js:5639)
同样,<Modal>
打开在本地很好。无需动动模块本身,是否有更简单的解决方法或解决方案?
这是我的父组件:
import React, { Component } from "react";
import RecurringOutageComponent from "./components/RecurringOutageComponent";
import FutureOutageComponent from "./components/FutureOutageComponent";
import CurrentOutagesComponent from "./components/CurrentOutagesComponent";
import CreateModalComponent from "./components/CreateModalComponent";
import { Container, Row, Col, Image } from "react-bootstrap";
import { getFutureOutages } from "./actions/fetchFutureOutagesAction";
import { getRecurringOutages } from "./actions/fetchRecurringOutagesAction";
import { getServices } from "./actions/fetchServicesAction";
import { getCurrentOutages } from "./actions/fetchCurrentOutagesAction";
import { connect } from 'react-redux';
class Dashboard extends Component {
state = {
showModal: false
};
componentDidMount() {
this.props.getFutureOutages()
this.props.getRecurringOutages()
this.props.getServices()
this.props.getCurrentOutages()
}
render() {
console.log(this.props)
return (
<div>
<Container>
<Row>
<Col lg={1}>
<img
src={require("./public/logo-2-dashboard.png")}
alt="logo"
id="logo"
></img>
</Col>
<Col md={10}></Col>
</Row>
</Container>
<Container>
<div className="d-flex justify-content-md-end bd-highlight">
<CreateModalComponent
show={this.state.showModal}
services={this.props.services}
/>
</div>
</Container>
<div className="d-flex justify-content-center bd-highlight dashboard">
<div className="d-flex justify-content-start bd-highlight">
<div className="d-fliex pastOutages">
<h4>Past Outages</h4>
</div>
</div>
<div className="d-flex justify-content-center bd-highlight">
<div className="d-fliex currentOutages">
<h4>Current Outages</h4>
<div className="container">
<div className="col-12">
<CurrentOutagesComponent />
</div>
</div>
</div>
</div>
<div className="d-flex align-items-center flex-column bd-highlight">
<div className="d-fliex justify-content-center">
<h4>Future Outages</h4>
<div className="container" id="futureOutages">
<div className="col-12">
<FutureOutageComponent
/>
</div>
</div>
<h4>Recurring Outages</h4>
<Container id="recurringOutages">
<div className="col-12">
<RecurringOutageComponent
/>
</div>
</Container>
</div>
</div>
</div>
</div>
);
}
}
const mapStateToProps = state => {
return {
outages: state.outages,
futureOutages: state.futureOutages.futureOutages,
recurringOutages: state.recurringOutages.recurringOutages,
services: state.services.services,
currentOutages: state.currentOutages.currentOutages
}
};
const mapDispatchToProps = dispatch => {
return {
getOutages: () => dispatch(getOutages()),
getFutureOutages: () => dispatch(getFutureOutages()),
getRecurringOutages: () => dispatch(getRecurringOutages()),
getServices: () => dispatch(getServices()),
getCurrentOutages: () => dispatch(getCurrentOutages())
};
};
export default connect(mapStateToProps, mapDispatchToProps)(Dashboard); // this connects Dashboard to store
这是包含其<Modal>
自身的创建组件:
import React, { Component } from "react";
import {
Modal,
Button,
Form,
InputGroup,
DropdownButton,
Dropdown,
FormControl
} from "react-bootstrap";
import DateTimePicker from "react-datetime-picker";
import { createFutureOutage } from "../actions/createFutureOutageAction";
import { createRecurringOutage } from "../actions/createRecurringOutageAction";
import { connect } from "react-redux";
const uuidv4 = require("uuid/v4");
import Moment from "react-moment";
import "moment-timezone";
class CreateModalComponent extends Component {
state = {
showModal: false,
startTime: new Date(),
endTime: new Date(),
service: "",
outageType: "",
frequency: "",
reason: ""
};
handleClose = () => this.setState({ showModal: false });
handleShow = () => this.setState({ showModal: true });
onChangeStart = date => {
this.setState({ startTime: date });
};
onChangeEnd = date => {
this.setState({ endTime: date });
};
handleChange = (name, value) => this.setState({ [name]: value });
handleReason = e => {
this.setState({ reason: e.currentTarget.value });
};
showFrequency = () => {
this.state.frequency === 0 ? "Frequency" : this.state.frequency;
};
handleSubmit = e => {
e.preventDefault();
const {
startTime,
endTime,
frequency,
outageType,
reason,
service,
outageId
} = this.state;
if (this.state.outageType === "FO") {
this.props.createFutureOutage(
startTime,
endTime,
frequency,
outageType,
reason,
service.id,
outageId
);
}
else if (this.state.outageType === "RO") {
this.props.createRecurringOutage(
startTime,
endTime,
frequency,
outageType,
reason,
service.id,
outageId
);
}
this.handleClose();
};
render() {
const frequency = ["Hourly", "Daily", "Weekly", "Monthly", "None"];
const outageType = ["FO", "RO"];
return (
<>
<Button variant="outline-primary" onClick={this.handleShow}>
Create Outage
</Button>
<Modal
show={this.state.showModal}
onHide={this.handleClose}
animation={false}
>
<Modal.Header closeButton>
<Modal.Title>Create Outage</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form onSubmit={e => this.handleSubmit(e)}>
<Form.Group>
Start Date
<DateTimePicker
onChange={this.onChangeStart}
value={this.state.startTime}
returnValue="start"
/>
</Form.Group>
<Form.Group>
End Date
<DateTimePicker
onChange={this.onChangeEnd}
value={this.state.endTime}
returnValue="end"
/>
<DropdownButton
as={InputGroup.Prepend}
variant="outline-secondary"
title={
this.state.service.length === 0
? "Service"
: this.state.service.service
}
id="input-group-dropdown-1"
>
{this.props.services.map(service => {
return (
<Dropdown.Item
key={uuidv4()}
onSelect={() => this.handleChange("service", service)}
>
{service.service}
</Dropdown.Item>
);
})}
</DropdownButton>
<DropdownButton
as={InputGroup.Prepend}
variant="outline-secondary"
title={
this.state.outageType.length === 0
? "Outage Type"
: this.state.outageType
}
id="input-group-dropdown-1"
>
{outageType.map((outage) => {
return (
<Dropdown.Item
key={uuidv4()}
onSelect={() => this.handleChange("outageType", outage)}
>
{outage}
</Dropdown.Item>
);
})}
</DropdownButton>
{this.state.outageType === "RO" ? (
<DropdownButton
as={InputGroup.Prepend}
variant="outline-secondary"
title={
this.state.frequency === ""
? "Frequency"
: this.state.frequency
}
id="input-group-dropdown-1"
>
{frequency.map((freq, idx) => {
return (
<Dropdown.Item
key={idx}
onSelect={() => this.handleChange("frequency", freq)}
>
{freq}
</Dropdown.Item>
);
})}
</DropdownButton>
) : null}
<Form.Group controlId="exampleForm.ControlTextarea1">
<Form.Label>Reason</Form.Label>
<Form.Control
as="textarea"
onChange={e => this.handleReason(e)}
rows="3"
/>
</Form.Group>
</Form.Group>
<Button variant="primary" type="submit">
Submit
</Button>
</Form>
</Modal.Body>
</Modal>
</>
);
}
}
const mapDispatchToProps = dispatch => {
return {
createFutureOutage: (startTime, endTime, frequency, outageType, reason, serviceId) =>
dispatch(createFutureOutage(
startTime,
endTime,
frequency,
outageType,
reason,
serviceId
)
),
createRecurringOutage: (startTime, endTime, frequency, outageType, reason, serviceId) =>
dispatch(createRecurringOutage(
startTime,
endTime,
frequency,
outageType,
reason,
serviceId
)
)
};
};
export default connect(null, mapDispatchToProps)(CreateModalComponent);
另外,我的NPM软件包的安装深度为1
Users/demiansims/.nvm/versions/node/v8.16.0/lib
├─┬ [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ └── [email protected]
└─┬ [email protected] -> /Users/demiansims/Development/tml_info/tml_dashboard
├── @babel/[email protected]
├── @rails/[email protected]
├── @rails/[email protected]
├── @rails/[email protected]
├── @rails/[email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
└── [email protected]
假设propTypes
在prod中定义了ReactBootstrap似乎是一个问题。
您可以更新Railsbabel.config.js
文件以忽略babel-plugin-transform-react-remove-prop-types
实际上是引起错误的原因。
例如,您可以注释掉这些行,并留下注释其原因的注释。例如
// babel.config.js
// Remove babel-plugin-transform-react-remove-prop-types to get
// [email protected] working properly
// isProductionEnv && [
// 'babel-plugin-transform-react-remove-prop-types',
// {
// removeImport: true
// }
// ]
在BootstrapReact的Github存储库中查看问题
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句