How to properly split the code of a component into sub-components?












-3












$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);









share|improve this question







New contributor




ScalaBoy is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$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
















-3












$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);









share|improve this question







New contributor




ScalaBoy is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$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














-3












-3








-3





$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);









share|improve this question







New contributor




ScalaBoy is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$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






share|improve this question







New contributor




ScalaBoy is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question







New contributor




ScalaBoy is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question






New contributor




ScalaBoy is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 16 hours ago









ScalaBoyScalaBoy

1




1




New contributor




ScalaBoy is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





ScalaBoy is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






ScalaBoy is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








  • 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




    $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










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.










draft saved

draft discarded


















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.










draft saved

draft discarded


















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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

Сан-Квентин

Алькесар

Josef Freinademetz