How to properly split the code of a component into sub-components?
$begingroup$
I have a component MyComp
with a long code that I want to split into 3 components.
My goal is to get the following setup of MyComp
. I appreciate general guidelines and a small example in an answer:
import React, { Component, Fragment } from 'react'
import { TopControls, Main, BottomBar } from './layouts'
export default class extends Component {
render() {
return <Fragment>
<TopControls />
<Main />
<BottomBar />
</Fragment>
}
}
Below I provide the code of MyComp
. My particular doubt is where should I move const styles
and all functions, e.g. updateDelay
, etc., because they would be shared among components TopControls
, Main
and BottomBar
:
import React from 'react';
import PropTypes from 'prop-types';
import withStyles from '@material-ui/core/styles/withStyles';
import CssBaseline from '@material-ui/core/CssBaseline';
import Grid from '@material-ui/core/Grid';
import Button from '@material-ui/core/Button';
import Icon from '@material-ui/core/Icon';
import TextField from '@material-ui/core/TextField';
import LinePlot from '../chart/LinePlot';
import BrushBarPlot from '../chart/BrushBarPlot';
import FormControl from '@material-ui/core/FormControl';
import Input from '@material-ui/core/Input';
import InputLabel from '@material-ui/core/InputLabel';
import MenuItem from '@material-ui/core/MenuItem';
import Select from '@material-ui/core/Select';
import Card from '@material-ui/core/Card';
import CardActionArea from '@material-ui/core/CardActionArea';
import CardContent from '@material-ui/core/CardContent';
import AppBar from '@material-ui/core/AppBar';
import InputAdornment from '@material-ui/core/InputAdornment';
const styles = theme => ({
header: {
borderBottom: 'solid 1px rgba(0,0,0,0.4)',
backgroundColor: '#253069',
color: '#d2d6ef',
overflow: 'hidden',
boxShadow: '0 2px 4px rgba(0,0,0,0.2)',
position: 'relative',
height: '12%'
},
h1: {
fontSize: '30px',
textAlign: 'center',
fontFamily: 'sans-serif',
lineHeight: '1.45em',
webkitFontSmoothing: 'antialiased'
},
h3: {
fontSize: '20px',
textAlign: 'left',
fontFamily: 'sans-serif',
lineHeight: '1.45em',
marginLeft: theme.spacing.unit*2,
webkitFontSmoothing: 'antialiased'
},
appBar: {
top: 'auto',
bottom: 5,
height: '10%'
},
toolbar: {
alignItems: "center",
justifyContent: "space-between"
},
textField: {
fontSize: '12px',
margin: theme.spacing.unit,
minWidth: 120
},
formControl: {
fontSize: '12px',
margin: theme.spacing.unit,
minWidth: 120
},
predictedDelay: {
marginTop: '10px',
position: 'relative',
minWidth: 350,
maxWidth: 350,
textAlign: 'center',
fontFamily: 'sans-serif',
backgroundColor: 'rgb(225, 0, 80)'
},
predictedDelayText: {
fontSize: '18px'
},
topControls: {
borderBottom: '1px solid #ddd',
height: '25%',
boxShadow: '0 1px 4px rgba(0,0,0,0.08)',
background: 'white',
marginLeft: theme.spacing.unit*2,
marginRight: theme.spacing.unit*2,
},
mainPart: {
webkitJustifyContent: 'space-between',
justifyContent: 'space-between',
marginTop: '30px',
marginBottom: '50px',
paddingTop: '2px',
position: 'relative',
backgroundColor: '#f7f7f7'
},
card: {
maxWidth: 200
},
paper: {
backgroundColor: '#f7f7f7',
padding: theme.spacing.unit * 2,
height: '70%',
marginLeft: theme.spacing.unit * 2,
marginRight: theme.spacing.unit * 2,
},
buttons: {
display: 'flex',
justifyContent: 'flex-end',
},
rightIcon: {
marginLeft: theme.spacing.unit,
},
button: {
marginTop: theme.spacing.unit * 3,
marginLeft: theme.spacing.unit,
}
});
class MyComp extends React.Component {
constructor(props) {
super(props);
this.state = {
holdingTime: 1,
plannedDep: "2017-05-24T10:30",
schedTurnd: 45,
asma40: 100,
asma60: 500,
taxiInTime: 9.50,
wake: 84.73,
temperature: 20,
visibility: 5999.66,
windIntensity: 8.0,
arrivalDelay: 5,
distanceTarget: 500,,
delay: 0,
delay_probability: 0,
delay_cat: "NA",
chartDataWake: ,
chartDataTurnaround: ,
chartDataArrivalDelay: ,
chartDataDistanceTarget: ,
labelWidth: 0
};
this.handleChange = this.handleChange.bind(this);
};
componentDidMount() {
this.fetchData();
};
updateDelay(predicted_delay,delay_probability) {
this.state.chartDataWake = [...this.state.chartDataWake, {wake: this.state.wake===84.73 ? "H" : (this.state.wake===14.78 ? "M" : "L"), delay: predicted_delay}];
this.state.chartDataTurnaround = [...this.state.chartDataTurnaround, {turnaround: this.state.schedTurnd, delay: predicted_delay}];
this.state.chartDataArrivalDelay = [...this.state.chartDataArrivalDelay, {arrivalDelay: this.state.arrivalDelay, delay: predicted_delay}];
this.state.chartDataDistanceTarget = [...this.state.chartDataDistanceTarget, {distanceTarget: this.state.distanceTarget, delay: predicted_delay}];
this.setState({
delay: predicted_delay,
delay_probability: delay_probability,
delay_cat: predicted_delay===0 ? "<15" : (predicted_delay===1 ? "[15; 45]" : ">45")
});
};
fetchData = () => {
const url = "http://localhost:8000?"+
'holdingTime='+this.state.holdingTime+
'&plannedDep='+this.state.plannedDep+
'&schedTurnd='+this.state.schedTurnd+
'&asma40='+this.state.asma40+
'&asma60='+this.state.asma60+
'&taxiInTime='+this.state.taxiInTime+
'&wake='+this.state.wake+
'&temperature='+this.state.temperature+
'&visibility='+this.state.visibility+
'&windIntensity='+this.state.windIntensity+
'&arrivalDelay='+this.state.arrivalDelay+
'&distanceTarget='+this.state.distanceTarget;
fetch(url, {
method: "GET",
dataType: "JSON",
headers: {
"Content-Type": "application/json; charset=utf-8",
}
})
.then((resp) => {
return resp.json()
})
.then((data) => {
this.updateDelay(data.prediction,data.probability)
})
.catch((error) => {
console.log(error, "catch the hoop")
})
};
handleChange = (name, event) => {
this.setState({
[name]: event.target.value
}, () => {
console.log("plannedDep",this.state.plannedDep)
});
};
handleReset = () => {
this.setState({
chartDataWake: ,
chartDataTurnaround: ,
chartDataArrivalDelay: ,
chartDataDistanceTarget: ,
delay: 0,
delay_probability: 0,
delay_cat: "NA"
});
};
render() {
const { classes } = this.props;
return (
<React.Fragment>
<CssBaseline />
<div className={classes.header}><h1 className={classes.h1}>Prediction of departure delays for a single flight</h1></div>
<div className={classes.topControls}>
<Grid container spacing={24}>
<Grid item xs={2}>
<TextField
required
id="outlined-simple-start-adornment"
className={classes.textField}
onChange={(event) => this.handleChange("holdingTime", event)}
value={this.state.holdingTime}
margin="normal"
label="Holding time"
type="number"
InputProps={{
startAdornment: <InputAdornment position="start">(seconds)</InputAdornment>,
}}
onInput = {(e) =>{
e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,12)
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Additional ASMA 40"
onChange={(event) => this.handleChange("asma40", event)}
value={this.state.asma40}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(minutes)</InputAdornment>,
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Additional ASMA 60"
onChange={(event) => this.handleChange("asma60", event)}
value={this.state.asma60}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(minutes)</InputAdornment>,
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
name="plannedDep"
id="datetime-local"
onChange={(event) => this.handleChange("plannedDep", event)}
value={this.state.plannedDep}
label="Scheduled departure"
type="datetime-local"
className={classes.textField}
margin="normal"
InputLabelProps={{
shrink: true,
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Planned turnaround"
onChange={(event) => this.handleChange("schedTurnd", event)}
value={this.state.schedTurnd}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(minutes)</InputAdornment>,
}}
onInput = {(e) =>{
e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,12)
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Taxi-In time"
onChange={(event) => this.handleChange("taxiInTime", event)}
value={this.state.taxiInTime}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(seconds)</InputAdornment>,
}}
onInput = {(e) =>{
e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,12)
}}
/>
</Grid>
</Grid>
<Grid container spacing={24}>
<Grid item xs={2}>
<FormControl
required
className={classes.formControl}
margin="normal">
<InputLabel shrink htmlFor="wake-label-placeholder">
Wake
</InputLabel>
<Select
onChange={(event) => this.handleChange("wake", event)}
value={this.state.wake}
input={<Input name="wake" id="wake-label-placeholder" />}
displayEmpty
name="wake"
>
<MenuItem value={84.73}>Heavy</MenuItem>
<MenuItem value={14.78}>Medium</MenuItem>
<MenuItem value={0.49}>Light</MenuItem>
</Select>
</FormControl>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Temperature"
onChange={(event) => this.handleChange("temperature", event)}
value={this.state.temperature}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(Celsius)</InputAdornment>,
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Visibility"
onChange={(event) => this.handleChange("visibility", event)}
value={this.state.visibility}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start"></InputAdornment>,
}}
onInput = {(e) =>{
e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,12)
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Wind Intensity"
onChange={(event) => this.handleChange("windIntensity", event)}
value={this.state.windIntensity}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(knots)</InputAdornment>,
}}
onInput = {(e) =>{
e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,12)
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Arrival delay"
onChange={(event) => this.handleChange("arrivalDelay", event)}
value={this.state.arrivalDelay}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(minutes)</InputAdornment>,
}}
onInput = {(e) =>{
e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,12)
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Distance to target"
onChange={(event) => this.handleChange("distanceTarget", event)}
value={this.state.distanceTarget}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(km)</InputAdornment>
}}
onInput = {(e) =>{
e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,12)
}}
/>
</Grid>
</Grid>
</div>
<main className={classes.mainPart}>
<Grid container spacing={24}>
<Grid item xs={12} sm={6} >
<div className={classes.h3}>Wake group</div>
<BrushBarPlot chartData={this.state.chartDataWake} varname="wake"/>
</Grid>
<Grid item xs={12} sm={6} className={classes.card}>
<div className={classes.h3}>Turnaround time</div>
<LinePlot chartData={this.state.chartDataTurnaround} varname="turnaround"/>
</Grid>
<Grid item xs={12} sm={6} >
<div className={classes.h3}>Arrival delay of a flight</div>
<LinePlot chartData={this.state.chartDataArrivalDelay} varname="arrivalDelay"/>
</Grid>
<Grid item xs={12} sm={6} className={classes.card}>
<div className={classes.h3}>Distance to target</div>
<LinePlot chartData={this.state.chartDataDistanceTarget} varname="distanceTarget"/>
</Grid>
</Grid>
</main>
<AppBar position="fixed" color="primary" className={classes.appBar}>
<div className={classes.toolbar}>
<Grid container spacing={24}>
<Grid item xs={6} sm={3}>
<Button variant="contained" color="primary" onClick={this.fetchData} className={classes.button}>
Predict
<Icon className={classes.rightIcon}>send</Icon>
</Button>
<Button variant="contained" color="primary" onClick={this.handleReset} className={classes.button}>
Reset
<Icon className={classes.rightIcon}>clear</Icon>
</Button>
</Grid>
<Grid item xs={6} sm={2}>
<Card className={classes.predictedDelay}>
<CardActionArea>
<CardContent>
<div className={classes.predictedDelayText}>
Delay class: {this.state.delay_cat} <span> </span>
(Prob.: {this.state.delay_probability})
</div>
</CardContent>
</CardActionArea>
</Card>
</Grid>
</Grid>
</div>
</AppBar>
</React.Fragment>
);
}
}
MyComp.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(MyComp);
javascript react.js
New contributor
$endgroup$
add a comment |
$begingroup$
I have a component MyComp
with a long code that I want to split into 3 components.
My goal is to get the following setup of MyComp
. I appreciate general guidelines and a small example in an answer:
import React, { Component, Fragment } from 'react'
import { TopControls, Main, BottomBar } from './layouts'
export default class extends Component {
render() {
return <Fragment>
<TopControls />
<Main />
<BottomBar />
</Fragment>
}
}
Below I provide the code of MyComp
. My particular doubt is where should I move const styles
and all functions, e.g. updateDelay
, etc., because they would be shared among components TopControls
, Main
and BottomBar
:
import React from 'react';
import PropTypes from 'prop-types';
import withStyles from '@material-ui/core/styles/withStyles';
import CssBaseline from '@material-ui/core/CssBaseline';
import Grid from '@material-ui/core/Grid';
import Button from '@material-ui/core/Button';
import Icon from '@material-ui/core/Icon';
import TextField from '@material-ui/core/TextField';
import LinePlot from '../chart/LinePlot';
import BrushBarPlot from '../chart/BrushBarPlot';
import FormControl from '@material-ui/core/FormControl';
import Input from '@material-ui/core/Input';
import InputLabel from '@material-ui/core/InputLabel';
import MenuItem from '@material-ui/core/MenuItem';
import Select from '@material-ui/core/Select';
import Card from '@material-ui/core/Card';
import CardActionArea from '@material-ui/core/CardActionArea';
import CardContent from '@material-ui/core/CardContent';
import AppBar from '@material-ui/core/AppBar';
import InputAdornment from '@material-ui/core/InputAdornment';
const styles = theme => ({
header: {
borderBottom: 'solid 1px rgba(0,0,0,0.4)',
backgroundColor: '#253069',
color: '#d2d6ef',
overflow: 'hidden',
boxShadow: '0 2px 4px rgba(0,0,0,0.2)',
position: 'relative',
height: '12%'
},
h1: {
fontSize: '30px',
textAlign: 'center',
fontFamily: 'sans-serif',
lineHeight: '1.45em',
webkitFontSmoothing: 'antialiased'
},
h3: {
fontSize: '20px',
textAlign: 'left',
fontFamily: 'sans-serif',
lineHeight: '1.45em',
marginLeft: theme.spacing.unit*2,
webkitFontSmoothing: 'antialiased'
},
appBar: {
top: 'auto',
bottom: 5,
height: '10%'
},
toolbar: {
alignItems: "center",
justifyContent: "space-between"
},
textField: {
fontSize: '12px',
margin: theme.spacing.unit,
minWidth: 120
},
formControl: {
fontSize: '12px',
margin: theme.spacing.unit,
minWidth: 120
},
predictedDelay: {
marginTop: '10px',
position: 'relative',
minWidth: 350,
maxWidth: 350,
textAlign: 'center',
fontFamily: 'sans-serif',
backgroundColor: 'rgb(225, 0, 80)'
},
predictedDelayText: {
fontSize: '18px'
},
topControls: {
borderBottom: '1px solid #ddd',
height: '25%',
boxShadow: '0 1px 4px rgba(0,0,0,0.08)',
background: 'white',
marginLeft: theme.spacing.unit*2,
marginRight: theme.spacing.unit*2,
},
mainPart: {
webkitJustifyContent: 'space-between',
justifyContent: 'space-between',
marginTop: '30px',
marginBottom: '50px',
paddingTop: '2px',
position: 'relative',
backgroundColor: '#f7f7f7'
},
card: {
maxWidth: 200
},
paper: {
backgroundColor: '#f7f7f7',
padding: theme.spacing.unit * 2,
height: '70%',
marginLeft: theme.spacing.unit * 2,
marginRight: theme.spacing.unit * 2,
},
buttons: {
display: 'flex',
justifyContent: 'flex-end',
},
rightIcon: {
marginLeft: theme.spacing.unit,
},
button: {
marginTop: theme.spacing.unit * 3,
marginLeft: theme.spacing.unit,
}
});
class MyComp extends React.Component {
constructor(props) {
super(props);
this.state = {
holdingTime: 1,
plannedDep: "2017-05-24T10:30",
schedTurnd: 45,
asma40: 100,
asma60: 500,
taxiInTime: 9.50,
wake: 84.73,
temperature: 20,
visibility: 5999.66,
windIntensity: 8.0,
arrivalDelay: 5,
distanceTarget: 500,,
delay: 0,
delay_probability: 0,
delay_cat: "NA",
chartDataWake: ,
chartDataTurnaround: ,
chartDataArrivalDelay: ,
chartDataDistanceTarget: ,
labelWidth: 0
};
this.handleChange = this.handleChange.bind(this);
};
componentDidMount() {
this.fetchData();
};
updateDelay(predicted_delay,delay_probability) {
this.state.chartDataWake = [...this.state.chartDataWake, {wake: this.state.wake===84.73 ? "H" : (this.state.wake===14.78 ? "M" : "L"), delay: predicted_delay}];
this.state.chartDataTurnaround = [...this.state.chartDataTurnaround, {turnaround: this.state.schedTurnd, delay: predicted_delay}];
this.state.chartDataArrivalDelay = [...this.state.chartDataArrivalDelay, {arrivalDelay: this.state.arrivalDelay, delay: predicted_delay}];
this.state.chartDataDistanceTarget = [...this.state.chartDataDistanceTarget, {distanceTarget: this.state.distanceTarget, delay: predicted_delay}];
this.setState({
delay: predicted_delay,
delay_probability: delay_probability,
delay_cat: predicted_delay===0 ? "<15" : (predicted_delay===1 ? "[15; 45]" : ">45")
});
};
fetchData = () => {
const url = "http://localhost:8000?"+
'holdingTime='+this.state.holdingTime+
'&plannedDep='+this.state.plannedDep+
'&schedTurnd='+this.state.schedTurnd+
'&asma40='+this.state.asma40+
'&asma60='+this.state.asma60+
'&taxiInTime='+this.state.taxiInTime+
'&wake='+this.state.wake+
'&temperature='+this.state.temperature+
'&visibility='+this.state.visibility+
'&windIntensity='+this.state.windIntensity+
'&arrivalDelay='+this.state.arrivalDelay+
'&distanceTarget='+this.state.distanceTarget;
fetch(url, {
method: "GET",
dataType: "JSON",
headers: {
"Content-Type": "application/json; charset=utf-8",
}
})
.then((resp) => {
return resp.json()
})
.then((data) => {
this.updateDelay(data.prediction,data.probability)
})
.catch((error) => {
console.log(error, "catch the hoop")
})
};
handleChange = (name, event) => {
this.setState({
[name]: event.target.value
}, () => {
console.log("plannedDep",this.state.plannedDep)
});
};
handleReset = () => {
this.setState({
chartDataWake: ,
chartDataTurnaround: ,
chartDataArrivalDelay: ,
chartDataDistanceTarget: ,
delay: 0,
delay_probability: 0,
delay_cat: "NA"
});
};
render() {
const { classes } = this.props;
return (
<React.Fragment>
<CssBaseline />
<div className={classes.header}><h1 className={classes.h1}>Prediction of departure delays for a single flight</h1></div>
<div className={classes.topControls}>
<Grid container spacing={24}>
<Grid item xs={2}>
<TextField
required
id="outlined-simple-start-adornment"
className={classes.textField}
onChange={(event) => this.handleChange("holdingTime", event)}
value={this.state.holdingTime}
margin="normal"
label="Holding time"
type="number"
InputProps={{
startAdornment: <InputAdornment position="start">(seconds)</InputAdornment>,
}}
onInput = {(e) =>{
e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,12)
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Additional ASMA 40"
onChange={(event) => this.handleChange("asma40", event)}
value={this.state.asma40}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(minutes)</InputAdornment>,
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Additional ASMA 60"
onChange={(event) => this.handleChange("asma60", event)}
value={this.state.asma60}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(minutes)</InputAdornment>,
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
name="plannedDep"
id="datetime-local"
onChange={(event) => this.handleChange("plannedDep", event)}
value={this.state.plannedDep}
label="Scheduled departure"
type="datetime-local"
className={classes.textField}
margin="normal"
InputLabelProps={{
shrink: true,
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Planned turnaround"
onChange={(event) => this.handleChange("schedTurnd", event)}
value={this.state.schedTurnd}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(minutes)</InputAdornment>,
}}
onInput = {(e) =>{
e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,12)
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Taxi-In time"
onChange={(event) => this.handleChange("taxiInTime", event)}
value={this.state.taxiInTime}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(seconds)</InputAdornment>,
}}
onInput = {(e) =>{
e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,12)
}}
/>
</Grid>
</Grid>
<Grid container spacing={24}>
<Grid item xs={2}>
<FormControl
required
className={classes.formControl}
margin="normal">
<InputLabel shrink htmlFor="wake-label-placeholder">
Wake
</InputLabel>
<Select
onChange={(event) => this.handleChange("wake", event)}
value={this.state.wake}
input={<Input name="wake" id="wake-label-placeholder" />}
displayEmpty
name="wake"
>
<MenuItem value={84.73}>Heavy</MenuItem>
<MenuItem value={14.78}>Medium</MenuItem>
<MenuItem value={0.49}>Light</MenuItem>
</Select>
</FormControl>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Temperature"
onChange={(event) => this.handleChange("temperature", event)}
value={this.state.temperature}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(Celsius)</InputAdornment>,
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Visibility"
onChange={(event) => this.handleChange("visibility", event)}
value={this.state.visibility}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start"></InputAdornment>,
}}
onInput = {(e) =>{
e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,12)
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Wind Intensity"
onChange={(event) => this.handleChange("windIntensity", event)}
value={this.state.windIntensity}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(knots)</InputAdornment>,
}}
onInput = {(e) =>{
e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,12)
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Arrival delay"
onChange={(event) => this.handleChange("arrivalDelay", event)}
value={this.state.arrivalDelay}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(minutes)</InputAdornment>,
}}
onInput = {(e) =>{
e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,12)
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Distance to target"
onChange={(event) => this.handleChange("distanceTarget", event)}
value={this.state.distanceTarget}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(km)</InputAdornment>
}}
onInput = {(e) =>{
e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,12)
}}
/>
</Grid>
</Grid>
</div>
<main className={classes.mainPart}>
<Grid container spacing={24}>
<Grid item xs={12} sm={6} >
<div className={classes.h3}>Wake group</div>
<BrushBarPlot chartData={this.state.chartDataWake} varname="wake"/>
</Grid>
<Grid item xs={12} sm={6} className={classes.card}>
<div className={classes.h3}>Turnaround time</div>
<LinePlot chartData={this.state.chartDataTurnaround} varname="turnaround"/>
</Grid>
<Grid item xs={12} sm={6} >
<div className={classes.h3}>Arrival delay of a flight</div>
<LinePlot chartData={this.state.chartDataArrivalDelay} varname="arrivalDelay"/>
</Grid>
<Grid item xs={12} sm={6} className={classes.card}>
<div className={classes.h3}>Distance to target</div>
<LinePlot chartData={this.state.chartDataDistanceTarget} varname="distanceTarget"/>
</Grid>
</Grid>
</main>
<AppBar position="fixed" color="primary" className={classes.appBar}>
<div className={classes.toolbar}>
<Grid container spacing={24}>
<Grid item xs={6} sm={3}>
<Button variant="contained" color="primary" onClick={this.fetchData} className={classes.button}>
Predict
<Icon className={classes.rightIcon}>send</Icon>
</Button>
<Button variant="contained" color="primary" onClick={this.handleReset} className={classes.button}>
Reset
<Icon className={classes.rightIcon}>clear</Icon>
</Button>
</Grid>
<Grid item xs={6} sm={2}>
<Card className={classes.predictedDelay}>
<CardActionArea>
<CardContent>
<div className={classes.predictedDelayText}>
Delay class: {this.state.delay_cat} <span> </span>
(Prob.: {this.state.delay_probability})
</div>
</CardContent>
</CardActionArea>
</Card>
</Grid>
</Grid>
</div>
</AppBar>
</React.Fragment>
);
}
}
MyComp.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(MyComp);
javascript react.js
New contributor
$endgroup$
1
$begingroup$
Welcome to Code Review! I'm afraid this question does not match what this site is about. Code Review is about improving existing, working code. Code Review is not the site to ask for help in changing the structure of your code. Once you've made your changes, we would love to see it and comment on its new structure! Please see our help center for more information.
$endgroup$
– Toby Speight
16 hours ago
1
$begingroup$
When you say that you believe that the code should be modularized in a certain way, in a sense, that is already a review of your own code. It seems like this question is just asking for your desired code to be written for you.
$endgroup$
– 200_success
15 hours ago
add a comment |
$begingroup$
I have a component MyComp
with a long code that I want to split into 3 components.
My goal is to get the following setup of MyComp
. I appreciate general guidelines and a small example in an answer:
import React, { Component, Fragment } from 'react'
import { TopControls, Main, BottomBar } from './layouts'
export default class extends Component {
render() {
return <Fragment>
<TopControls />
<Main />
<BottomBar />
</Fragment>
}
}
Below I provide the code of MyComp
. My particular doubt is where should I move const styles
and all functions, e.g. updateDelay
, etc., because they would be shared among components TopControls
, Main
and BottomBar
:
import React from 'react';
import PropTypes from 'prop-types';
import withStyles from '@material-ui/core/styles/withStyles';
import CssBaseline from '@material-ui/core/CssBaseline';
import Grid from '@material-ui/core/Grid';
import Button from '@material-ui/core/Button';
import Icon from '@material-ui/core/Icon';
import TextField from '@material-ui/core/TextField';
import LinePlot from '../chart/LinePlot';
import BrushBarPlot from '../chart/BrushBarPlot';
import FormControl from '@material-ui/core/FormControl';
import Input from '@material-ui/core/Input';
import InputLabel from '@material-ui/core/InputLabel';
import MenuItem from '@material-ui/core/MenuItem';
import Select from '@material-ui/core/Select';
import Card from '@material-ui/core/Card';
import CardActionArea from '@material-ui/core/CardActionArea';
import CardContent from '@material-ui/core/CardContent';
import AppBar from '@material-ui/core/AppBar';
import InputAdornment from '@material-ui/core/InputAdornment';
const styles = theme => ({
header: {
borderBottom: 'solid 1px rgba(0,0,0,0.4)',
backgroundColor: '#253069',
color: '#d2d6ef',
overflow: 'hidden',
boxShadow: '0 2px 4px rgba(0,0,0,0.2)',
position: 'relative',
height: '12%'
},
h1: {
fontSize: '30px',
textAlign: 'center',
fontFamily: 'sans-serif',
lineHeight: '1.45em',
webkitFontSmoothing: 'antialiased'
},
h3: {
fontSize: '20px',
textAlign: 'left',
fontFamily: 'sans-serif',
lineHeight: '1.45em',
marginLeft: theme.spacing.unit*2,
webkitFontSmoothing: 'antialiased'
},
appBar: {
top: 'auto',
bottom: 5,
height: '10%'
},
toolbar: {
alignItems: "center",
justifyContent: "space-between"
},
textField: {
fontSize: '12px',
margin: theme.spacing.unit,
minWidth: 120
},
formControl: {
fontSize: '12px',
margin: theme.spacing.unit,
minWidth: 120
},
predictedDelay: {
marginTop: '10px',
position: 'relative',
minWidth: 350,
maxWidth: 350,
textAlign: 'center',
fontFamily: 'sans-serif',
backgroundColor: 'rgb(225, 0, 80)'
},
predictedDelayText: {
fontSize: '18px'
},
topControls: {
borderBottom: '1px solid #ddd',
height: '25%',
boxShadow: '0 1px 4px rgba(0,0,0,0.08)',
background: 'white',
marginLeft: theme.spacing.unit*2,
marginRight: theme.spacing.unit*2,
},
mainPart: {
webkitJustifyContent: 'space-between',
justifyContent: 'space-between',
marginTop: '30px',
marginBottom: '50px',
paddingTop: '2px',
position: 'relative',
backgroundColor: '#f7f7f7'
},
card: {
maxWidth: 200
},
paper: {
backgroundColor: '#f7f7f7',
padding: theme.spacing.unit * 2,
height: '70%',
marginLeft: theme.spacing.unit * 2,
marginRight: theme.spacing.unit * 2,
},
buttons: {
display: 'flex',
justifyContent: 'flex-end',
},
rightIcon: {
marginLeft: theme.spacing.unit,
},
button: {
marginTop: theme.spacing.unit * 3,
marginLeft: theme.spacing.unit,
}
});
class MyComp extends React.Component {
constructor(props) {
super(props);
this.state = {
holdingTime: 1,
plannedDep: "2017-05-24T10:30",
schedTurnd: 45,
asma40: 100,
asma60: 500,
taxiInTime: 9.50,
wake: 84.73,
temperature: 20,
visibility: 5999.66,
windIntensity: 8.0,
arrivalDelay: 5,
distanceTarget: 500,,
delay: 0,
delay_probability: 0,
delay_cat: "NA",
chartDataWake: ,
chartDataTurnaround: ,
chartDataArrivalDelay: ,
chartDataDistanceTarget: ,
labelWidth: 0
};
this.handleChange = this.handleChange.bind(this);
};
componentDidMount() {
this.fetchData();
};
updateDelay(predicted_delay,delay_probability) {
this.state.chartDataWake = [...this.state.chartDataWake, {wake: this.state.wake===84.73 ? "H" : (this.state.wake===14.78 ? "M" : "L"), delay: predicted_delay}];
this.state.chartDataTurnaround = [...this.state.chartDataTurnaround, {turnaround: this.state.schedTurnd, delay: predicted_delay}];
this.state.chartDataArrivalDelay = [...this.state.chartDataArrivalDelay, {arrivalDelay: this.state.arrivalDelay, delay: predicted_delay}];
this.state.chartDataDistanceTarget = [...this.state.chartDataDistanceTarget, {distanceTarget: this.state.distanceTarget, delay: predicted_delay}];
this.setState({
delay: predicted_delay,
delay_probability: delay_probability,
delay_cat: predicted_delay===0 ? "<15" : (predicted_delay===1 ? "[15; 45]" : ">45")
});
};
fetchData = () => {
const url = "http://localhost:8000?"+
'holdingTime='+this.state.holdingTime+
'&plannedDep='+this.state.plannedDep+
'&schedTurnd='+this.state.schedTurnd+
'&asma40='+this.state.asma40+
'&asma60='+this.state.asma60+
'&taxiInTime='+this.state.taxiInTime+
'&wake='+this.state.wake+
'&temperature='+this.state.temperature+
'&visibility='+this.state.visibility+
'&windIntensity='+this.state.windIntensity+
'&arrivalDelay='+this.state.arrivalDelay+
'&distanceTarget='+this.state.distanceTarget;
fetch(url, {
method: "GET",
dataType: "JSON",
headers: {
"Content-Type": "application/json; charset=utf-8",
}
})
.then((resp) => {
return resp.json()
})
.then((data) => {
this.updateDelay(data.prediction,data.probability)
})
.catch((error) => {
console.log(error, "catch the hoop")
})
};
handleChange = (name, event) => {
this.setState({
[name]: event.target.value
}, () => {
console.log("plannedDep",this.state.plannedDep)
});
};
handleReset = () => {
this.setState({
chartDataWake: ,
chartDataTurnaround: ,
chartDataArrivalDelay: ,
chartDataDistanceTarget: ,
delay: 0,
delay_probability: 0,
delay_cat: "NA"
});
};
render() {
const { classes } = this.props;
return (
<React.Fragment>
<CssBaseline />
<div className={classes.header}><h1 className={classes.h1}>Prediction of departure delays for a single flight</h1></div>
<div className={classes.topControls}>
<Grid container spacing={24}>
<Grid item xs={2}>
<TextField
required
id="outlined-simple-start-adornment"
className={classes.textField}
onChange={(event) => this.handleChange("holdingTime", event)}
value={this.state.holdingTime}
margin="normal"
label="Holding time"
type="number"
InputProps={{
startAdornment: <InputAdornment position="start">(seconds)</InputAdornment>,
}}
onInput = {(e) =>{
e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,12)
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Additional ASMA 40"
onChange={(event) => this.handleChange("asma40", event)}
value={this.state.asma40}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(minutes)</InputAdornment>,
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Additional ASMA 60"
onChange={(event) => this.handleChange("asma60", event)}
value={this.state.asma60}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(minutes)</InputAdornment>,
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
name="plannedDep"
id="datetime-local"
onChange={(event) => this.handleChange("plannedDep", event)}
value={this.state.plannedDep}
label="Scheduled departure"
type="datetime-local"
className={classes.textField}
margin="normal"
InputLabelProps={{
shrink: true,
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Planned turnaround"
onChange={(event) => this.handleChange("schedTurnd", event)}
value={this.state.schedTurnd}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(minutes)</InputAdornment>,
}}
onInput = {(e) =>{
e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,12)
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Taxi-In time"
onChange={(event) => this.handleChange("taxiInTime", event)}
value={this.state.taxiInTime}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(seconds)</InputAdornment>,
}}
onInput = {(e) =>{
e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,12)
}}
/>
</Grid>
</Grid>
<Grid container spacing={24}>
<Grid item xs={2}>
<FormControl
required
className={classes.formControl}
margin="normal">
<InputLabel shrink htmlFor="wake-label-placeholder">
Wake
</InputLabel>
<Select
onChange={(event) => this.handleChange("wake", event)}
value={this.state.wake}
input={<Input name="wake" id="wake-label-placeholder" />}
displayEmpty
name="wake"
>
<MenuItem value={84.73}>Heavy</MenuItem>
<MenuItem value={14.78}>Medium</MenuItem>
<MenuItem value={0.49}>Light</MenuItem>
</Select>
</FormControl>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Temperature"
onChange={(event) => this.handleChange("temperature", event)}
value={this.state.temperature}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(Celsius)</InputAdornment>,
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Visibility"
onChange={(event) => this.handleChange("visibility", event)}
value={this.state.visibility}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start"></InputAdornment>,
}}
onInput = {(e) =>{
e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,12)
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Wind Intensity"
onChange={(event) => this.handleChange("windIntensity", event)}
value={this.state.windIntensity}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(knots)</InputAdornment>,
}}
onInput = {(e) =>{
e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,12)
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Arrival delay"
onChange={(event) => this.handleChange("arrivalDelay", event)}
value={this.state.arrivalDelay}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(minutes)</InputAdornment>,
}}
onInput = {(e) =>{
e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,12)
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Distance to target"
onChange={(event) => this.handleChange("distanceTarget", event)}
value={this.state.distanceTarget}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(km)</InputAdornment>
}}
onInput = {(e) =>{
e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,12)
}}
/>
</Grid>
</Grid>
</div>
<main className={classes.mainPart}>
<Grid container spacing={24}>
<Grid item xs={12} sm={6} >
<div className={classes.h3}>Wake group</div>
<BrushBarPlot chartData={this.state.chartDataWake} varname="wake"/>
</Grid>
<Grid item xs={12} sm={6} className={classes.card}>
<div className={classes.h3}>Turnaround time</div>
<LinePlot chartData={this.state.chartDataTurnaround} varname="turnaround"/>
</Grid>
<Grid item xs={12} sm={6} >
<div className={classes.h3}>Arrival delay of a flight</div>
<LinePlot chartData={this.state.chartDataArrivalDelay} varname="arrivalDelay"/>
</Grid>
<Grid item xs={12} sm={6} className={classes.card}>
<div className={classes.h3}>Distance to target</div>
<LinePlot chartData={this.state.chartDataDistanceTarget} varname="distanceTarget"/>
</Grid>
</Grid>
</main>
<AppBar position="fixed" color="primary" className={classes.appBar}>
<div className={classes.toolbar}>
<Grid container spacing={24}>
<Grid item xs={6} sm={3}>
<Button variant="contained" color="primary" onClick={this.fetchData} className={classes.button}>
Predict
<Icon className={classes.rightIcon}>send</Icon>
</Button>
<Button variant="contained" color="primary" onClick={this.handleReset} className={classes.button}>
Reset
<Icon className={classes.rightIcon}>clear</Icon>
</Button>
</Grid>
<Grid item xs={6} sm={2}>
<Card className={classes.predictedDelay}>
<CardActionArea>
<CardContent>
<div className={classes.predictedDelayText}>
Delay class: {this.state.delay_cat} <span> </span>
(Prob.: {this.state.delay_probability})
</div>
</CardContent>
</CardActionArea>
</Card>
</Grid>
</Grid>
</div>
</AppBar>
</React.Fragment>
);
}
}
MyComp.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(MyComp);
javascript react.js
New contributor
$endgroup$
I have a component MyComp
with a long code that I want to split into 3 components.
My goal is to get the following setup of MyComp
. I appreciate general guidelines and a small example in an answer:
import React, { Component, Fragment } from 'react'
import { TopControls, Main, BottomBar } from './layouts'
export default class extends Component {
render() {
return <Fragment>
<TopControls />
<Main />
<BottomBar />
</Fragment>
}
}
Below I provide the code of MyComp
. My particular doubt is where should I move const styles
and all functions, e.g. updateDelay
, etc., because they would be shared among components TopControls
, Main
and BottomBar
:
import React from 'react';
import PropTypes from 'prop-types';
import withStyles from '@material-ui/core/styles/withStyles';
import CssBaseline from '@material-ui/core/CssBaseline';
import Grid from '@material-ui/core/Grid';
import Button from '@material-ui/core/Button';
import Icon from '@material-ui/core/Icon';
import TextField from '@material-ui/core/TextField';
import LinePlot from '../chart/LinePlot';
import BrushBarPlot from '../chart/BrushBarPlot';
import FormControl from '@material-ui/core/FormControl';
import Input from '@material-ui/core/Input';
import InputLabel from '@material-ui/core/InputLabel';
import MenuItem from '@material-ui/core/MenuItem';
import Select from '@material-ui/core/Select';
import Card from '@material-ui/core/Card';
import CardActionArea from '@material-ui/core/CardActionArea';
import CardContent from '@material-ui/core/CardContent';
import AppBar from '@material-ui/core/AppBar';
import InputAdornment from '@material-ui/core/InputAdornment';
const styles = theme => ({
header: {
borderBottom: 'solid 1px rgba(0,0,0,0.4)',
backgroundColor: '#253069',
color: '#d2d6ef',
overflow: 'hidden',
boxShadow: '0 2px 4px rgba(0,0,0,0.2)',
position: 'relative',
height: '12%'
},
h1: {
fontSize: '30px',
textAlign: 'center',
fontFamily: 'sans-serif',
lineHeight: '1.45em',
webkitFontSmoothing: 'antialiased'
},
h3: {
fontSize: '20px',
textAlign: 'left',
fontFamily: 'sans-serif',
lineHeight: '1.45em',
marginLeft: theme.spacing.unit*2,
webkitFontSmoothing: 'antialiased'
},
appBar: {
top: 'auto',
bottom: 5,
height: '10%'
},
toolbar: {
alignItems: "center",
justifyContent: "space-between"
},
textField: {
fontSize: '12px',
margin: theme.spacing.unit,
minWidth: 120
},
formControl: {
fontSize: '12px',
margin: theme.spacing.unit,
minWidth: 120
},
predictedDelay: {
marginTop: '10px',
position: 'relative',
minWidth: 350,
maxWidth: 350,
textAlign: 'center',
fontFamily: 'sans-serif',
backgroundColor: 'rgb(225, 0, 80)'
},
predictedDelayText: {
fontSize: '18px'
},
topControls: {
borderBottom: '1px solid #ddd',
height: '25%',
boxShadow: '0 1px 4px rgba(0,0,0,0.08)',
background: 'white',
marginLeft: theme.spacing.unit*2,
marginRight: theme.spacing.unit*2,
},
mainPart: {
webkitJustifyContent: 'space-between',
justifyContent: 'space-between',
marginTop: '30px',
marginBottom: '50px',
paddingTop: '2px',
position: 'relative',
backgroundColor: '#f7f7f7'
},
card: {
maxWidth: 200
},
paper: {
backgroundColor: '#f7f7f7',
padding: theme.spacing.unit * 2,
height: '70%',
marginLeft: theme.spacing.unit * 2,
marginRight: theme.spacing.unit * 2,
},
buttons: {
display: 'flex',
justifyContent: 'flex-end',
},
rightIcon: {
marginLeft: theme.spacing.unit,
},
button: {
marginTop: theme.spacing.unit * 3,
marginLeft: theme.spacing.unit,
}
});
class MyComp extends React.Component {
constructor(props) {
super(props);
this.state = {
holdingTime: 1,
plannedDep: "2017-05-24T10:30",
schedTurnd: 45,
asma40: 100,
asma60: 500,
taxiInTime: 9.50,
wake: 84.73,
temperature: 20,
visibility: 5999.66,
windIntensity: 8.0,
arrivalDelay: 5,
distanceTarget: 500,,
delay: 0,
delay_probability: 0,
delay_cat: "NA",
chartDataWake: ,
chartDataTurnaround: ,
chartDataArrivalDelay: ,
chartDataDistanceTarget: ,
labelWidth: 0
};
this.handleChange = this.handleChange.bind(this);
};
componentDidMount() {
this.fetchData();
};
updateDelay(predicted_delay,delay_probability) {
this.state.chartDataWake = [...this.state.chartDataWake, {wake: this.state.wake===84.73 ? "H" : (this.state.wake===14.78 ? "M" : "L"), delay: predicted_delay}];
this.state.chartDataTurnaround = [...this.state.chartDataTurnaround, {turnaround: this.state.schedTurnd, delay: predicted_delay}];
this.state.chartDataArrivalDelay = [...this.state.chartDataArrivalDelay, {arrivalDelay: this.state.arrivalDelay, delay: predicted_delay}];
this.state.chartDataDistanceTarget = [...this.state.chartDataDistanceTarget, {distanceTarget: this.state.distanceTarget, delay: predicted_delay}];
this.setState({
delay: predicted_delay,
delay_probability: delay_probability,
delay_cat: predicted_delay===0 ? "<15" : (predicted_delay===1 ? "[15; 45]" : ">45")
});
};
fetchData = () => {
const url = "http://localhost:8000?"+
'holdingTime='+this.state.holdingTime+
'&plannedDep='+this.state.plannedDep+
'&schedTurnd='+this.state.schedTurnd+
'&asma40='+this.state.asma40+
'&asma60='+this.state.asma60+
'&taxiInTime='+this.state.taxiInTime+
'&wake='+this.state.wake+
'&temperature='+this.state.temperature+
'&visibility='+this.state.visibility+
'&windIntensity='+this.state.windIntensity+
'&arrivalDelay='+this.state.arrivalDelay+
'&distanceTarget='+this.state.distanceTarget;
fetch(url, {
method: "GET",
dataType: "JSON",
headers: {
"Content-Type": "application/json; charset=utf-8",
}
})
.then((resp) => {
return resp.json()
})
.then((data) => {
this.updateDelay(data.prediction,data.probability)
})
.catch((error) => {
console.log(error, "catch the hoop")
})
};
handleChange = (name, event) => {
this.setState({
[name]: event.target.value
}, () => {
console.log("plannedDep",this.state.plannedDep)
});
};
handleReset = () => {
this.setState({
chartDataWake: ,
chartDataTurnaround: ,
chartDataArrivalDelay: ,
chartDataDistanceTarget: ,
delay: 0,
delay_probability: 0,
delay_cat: "NA"
});
};
render() {
const { classes } = this.props;
return (
<React.Fragment>
<CssBaseline />
<div className={classes.header}><h1 className={classes.h1}>Prediction of departure delays for a single flight</h1></div>
<div className={classes.topControls}>
<Grid container spacing={24}>
<Grid item xs={2}>
<TextField
required
id="outlined-simple-start-adornment"
className={classes.textField}
onChange={(event) => this.handleChange("holdingTime", event)}
value={this.state.holdingTime}
margin="normal"
label="Holding time"
type="number"
InputProps={{
startAdornment: <InputAdornment position="start">(seconds)</InputAdornment>,
}}
onInput = {(e) =>{
e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,12)
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Additional ASMA 40"
onChange={(event) => this.handleChange("asma40", event)}
value={this.state.asma40}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(minutes)</InputAdornment>,
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Additional ASMA 60"
onChange={(event) => this.handleChange("asma60", event)}
value={this.state.asma60}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(minutes)</InputAdornment>,
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
name="plannedDep"
id="datetime-local"
onChange={(event) => this.handleChange("plannedDep", event)}
value={this.state.plannedDep}
label="Scheduled departure"
type="datetime-local"
className={classes.textField}
margin="normal"
InputLabelProps={{
shrink: true,
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Planned turnaround"
onChange={(event) => this.handleChange("schedTurnd", event)}
value={this.state.schedTurnd}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(minutes)</InputAdornment>,
}}
onInput = {(e) =>{
e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,12)
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Taxi-In time"
onChange={(event) => this.handleChange("taxiInTime", event)}
value={this.state.taxiInTime}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(seconds)</InputAdornment>,
}}
onInput = {(e) =>{
e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,12)
}}
/>
</Grid>
</Grid>
<Grid container spacing={24}>
<Grid item xs={2}>
<FormControl
required
className={classes.formControl}
margin="normal">
<InputLabel shrink htmlFor="wake-label-placeholder">
Wake
</InputLabel>
<Select
onChange={(event) => this.handleChange("wake", event)}
value={this.state.wake}
input={<Input name="wake" id="wake-label-placeholder" />}
displayEmpty
name="wake"
>
<MenuItem value={84.73}>Heavy</MenuItem>
<MenuItem value={14.78}>Medium</MenuItem>
<MenuItem value={0.49}>Light</MenuItem>
</Select>
</FormControl>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Temperature"
onChange={(event) => this.handleChange("temperature", event)}
value={this.state.temperature}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(Celsius)</InputAdornment>,
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Visibility"
onChange={(event) => this.handleChange("visibility", event)}
value={this.state.visibility}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start"></InputAdornment>,
}}
onInput = {(e) =>{
e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,12)
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Wind Intensity"
onChange={(event) => this.handleChange("windIntensity", event)}
value={this.state.windIntensity}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(knots)</InputAdornment>,
}}
onInput = {(e) =>{
e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,12)
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Arrival delay"
onChange={(event) => this.handleChange("arrivalDelay", event)}
value={this.state.arrivalDelay}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(minutes)</InputAdornment>,
}}
onInput = {(e) =>{
e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,12)
}}
/>
</Grid>
<Grid item xs={2}>
<TextField
required
id="standard-number"
label="Distance to target"
onChange={(event) => this.handleChange("distanceTarget", event)}
value={this.state.distanceTarget}
type="number"
className={classes.textField}
margin="normal"
InputProps={{
startAdornment: <InputAdornment position="start">(km)</InputAdornment>
}}
onInput = {(e) =>{
e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,12)
}}
/>
</Grid>
</Grid>
</div>
<main className={classes.mainPart}>
<Grid container spacing={24}>
<Grid item xs={12} sm={6} >
<div className={classes.h3}>Wake group</div>
<BrushBarPlot chartData={this.state.chartDataWake} varname="wake"/>
</Grid>
<Grid item xs={12} sm={6} className={classes.card}>
<div className={classes.h3}>Turnaround time</div>
<LinePlot chartData={this.state.chartDataTurnaround} varname="turnaround"/>
</Grid>
<Grid item xs={12} sm={6} >
<div className={classes.h3}>Arrival delay of a flight</div>
<LinePlot chartData={this.state.chartDataArrivalDelay} varname="arrivalDelay"/>
</Grid>
<Grid item xs={12} sm={6} className={classes.card}>
<div className={classes.h3}>Distance to target</div>
<LinePlot chartData={this.state.chartDataDistanceTarget} varname="distanceTarget"/>
</Grid>
</Grid>
</main>
<AppBar position="fixed" color="primary" className={classes.appBar}>
<div className={classes.toolbar}>
<Grid container spacing={24}>
<Grid item xs={6} sm={3}>
<Button variant="contained" color="primary" onClick={this.fetchData} className={classes.button}>
Predict
<Icon className={classes.rightIcon}>send</Icon>
</Button>
<Button variant="contained" color="primary" onClick={this.handleReset} className={classes.button}>
Reset
<Icon className={classes.rightIcon}>clear</Icon>
</Button>
</Grid>
<Grid item xs={6} sm={2}>
<Card className={classes.predictedDelay}>
<CardActionArea>
<CardContent>
<div className={classes.predictedDelayText}>
Delay class: {this.state.delay_cat} <span> </span>
(Prob.: {this.state.delay_probability})
</div>
</CardContent>
</CardActionArea>
</Card>
</Grid>
</Grid>
</div>
</AppBar>
</React.Fragment>
);
}
}
MyComp.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(MyComp);
javascript react.js
javascript react.js
New contributor
New contributor
New contributor
asked 16 hours ago
ScalaBoyScalaBoy
1
1
New contributor
New contributor
1
$begingroup$
Welcome to Code Review! I'm afraid this question does not match what this site is about. Code Review is about improving existing, working code. Code Review is not the site to ask for help in changing the structure of your code. Once you've made your changes, we would love to see it and comment on its new structure! Please see our help center for more information.
$endgroup$
– Toby Speight
16 hours ago
1
$begingroup$
When you say that you believe that the code should be modularized in a certain way, in a sense, that is already a review of your own code. It seems like this question is just asking for your desired code to be written for you.
$endgroup$
– 200_success
15 hours ago
add a comment |
1
$begingroup$
Welcome to Code Review! I'm afraid this question does not match what this site is about. Code Review is about improving existing, working code. Code Review is not the site to ask for help in changing the structure of your code. Once you've made your changes, we would love to see it and comment on its new structure! Please see our help center for more information.
$endgroup$
– Toby Speight
16 hours ago
1
$begingroup$
When you say that you believe that the code should be modularized in a certain way, in a sense, that is already a review of your own code. It seems like this question is just asking for your desired code to be written for you.
$endgroup$
– 200_success
15 hours ago
1
1
$begingroup$
Welcome to Code Review! I'm afraid this question does not match what this site is about. Code Review is about improving existing, working code. Code Review is not the site to ask for help in changing the structure of your code. Once you've made your changes, we would love to see it and comment on its new structure! Please see our help center for more information.
$endgroup$
– Toby Speight
16 hours ago
$begingroup$
Welcome to Code Review! I'm afraid this question does not match what this site is about. Code Review is about improving existing, working code. Code Review is not the site to ask for help in changing the structure of your code. Once you've made your changes, we would love to see it and comment on its new structure! Please see our help center for more information.
$endgroup$
– Toby Speight
16 hours ago
1
1
$begingroup$
When you say that you believe that the code should be modularized in a certain way, in a sense, that is already a review of your own code. It seems like this question is just asking for your desired code to be written for you.
$endgroup$
– 200_success
15 hours ago
$begingroup$
When you say that you believe that the code should be modularized in a certain way, in a sense, that is already a review of your own code. It seems like this question is just asking for your desired code to be written for you.
$endgroup$
– 200_success
15 hours ago
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
ScalaBoy is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f211535%2fhow-to-properly-split-the-code-of-a-component-into-sub-components%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
ScalaBoy is a new contributor. Be nice, and check out our Code of Conduct.
ScalaBoy is a new contributor. Be nice, and check out our Code of Conduct.
ScalaBoy is a new contributor. Be nice, and check out our Code of Conduct.
ScalaBoy is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f211535%2fhow-to-properly-split-the-code-of-a-component-into-sub-components%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
$begingroup$
Welcome to Code Review! I'm afraid this question does not match what this site is about. Code Review is about improving existing, working code. Code Review is not the site to ask for help in changing the structure of your code. Once you've made your changes, we would love to see it and comment on its new structure! Please see our help center for more information.
$endgroup$
– Toby Speight
16 hours ago
1
$begingroup$
When you say that you believe that the code should be modularized in a certain way, in a sense, that is already a review of your own code. It seems like this question is just asking for your desired code to be written for you.
$endgroup$
– 200_success
15 hours ago