I have a class ponent which works as expected but now I would like to change this class ponent to functional ponent
Here is my class
import React, { Component } from 'react'
import EventCalendar from '../App';
import moment from 'moment';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
import Button from 'react-bootstrap/Button';
import ButtonToolbar from 'react-bootstrap/ButtonToolbar';
const events =[
{
title: 'Womens History Month ',
start: '2020-03-02',
end: '2020-03-02',
//description: '',
url: 'dev91b558163211cf9d2e7d1efe6c3e32035973fdf9',
eventClasses: 'event1'
},
];
export class CalendarDemo extends Component {
constructor(props) {
super(props);
this.state = {
moment: moment(),
};
this.handleNextMonth = this.handleNextMonth.bind(this);
this.handlePreviousMonth = this.handlePreviousMonth.bind(this);
this.handleToday = this.handleToday.bind(this);
this.handleEventClick = this.handleEventClick.bind(this);
this.handleEventMouseOver = this.handleEventMouseOver.bind(this);
this.handleEventMouseOut = this.handleEventMouseOut.bind(this);
this.handleDayClick = this.handleDayClick.bind(this);
}
handleNextMonth() {
this.setState({
moment: this.state.moment.add(1, 'M'),
});
}
handlePreviousMonth() {
this.setState({
moment: this.state.moment.subtract(1, 'M'),
});
}
handleToday() {
this.setState({
moment: moment(),
});
}
handleEventMouseOver(target, eventData, day) {
console.log("event data", target.props.eventData.url);
this.setState({
});
}
handleEventMouseOut(target, eventData, day) {
this.setState({
});
}
handleEventClick(target, eventData, day) {
this.setState({
});
}
handleDayClick(target, day) {
this.setState({
});
}
getMomentFromDay(day) {
return moment().set({
'year': day.year,
'month': (day.month + 0) % 12,
'date': day.day,
});
}
getHumanDate() {
return [moment.months('MM', this.state.moment.month()), this.state.moment.year(), ].join(' ');
}
render() {
return (
<div style={styles}>
<Row className='topBar'>
<Col xs={6}>
<ButtonToolbar>
<Button onClick={this.handlePreviousMonth}><</Button>
<Button onClick={this.handleNextMonth}>></Button>
<Button onClick={this.handleToday}>Today</Button>
</ButtonToolbar>
</Col>
<Col xs={6}>
<div className='pull-right h2'>{this.getHumanDate()}</div>
</Col>
</Row>
<br />
<Row>
<Col xs={12}>
<EventCalendar
month={this.state.moment.month()}
year={this.state.moment.year()}
events={events}
onEventClick={this.handleEventClick}
onEventMouseOver={this.handleEventMouseOver}
onEventMouseOut={this.handleEventMouseOut}
onDayClick={this.handleDayClick}
maxEventSlots={0}
/>
</Col>
</Row>
</div>
);
}
}
export default CalendarDemo
const styles = {
position: 'relative',
};
What do I need to change here so that I will get a functional ponent?
I have a class ponent which works as expected but now I would like to change this class ponent to functional ponent
Here is my class
import React, { Component } from 'react'
import EventCalendar from '../App';
import moment from 'moment';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
import Button from 'react-bootstrap/Button';
import ButtonToolbar from 'react-bootstrap/ButtonToolbar';
const events =[
{
title: 'Womens History Month ',
start: '2020-03-02',
end: '2020-03-02',
//description: '',
url: 'dev91b558163211cf9d2e7d1efe6c3e32035973fdf9',
eventClasses: 'event1'
},
];
export class CalendarDemo extends Component {
constructor(props) {
super(props);
this.state = {
moment: moment(),
};
this.handleNextMonth = this.handleNextMonth.bind(this);
this.handlePreviousMonth = this.handlePreviousMonth.bind(this);
this.handleToday = this.handleToday.bind(this);
this.handleEventClick = this.handleEventClick.bind(this);
this.handleEventMouseOver = this.handleEventMouseOver.bind(this);
this.handleEventMouseOut = this.handleEventMouseOut.bind(this);
this.handleDayClick = this.handleDayClick.bind(this);
}
handleNextMonth() {
this.setState({
moment: this.state.moment.add(1, 'M'),
});
}
handlePreviousMonth() {
this.setState({
moment: this.state.moment.subtract(1, 'M'),
});
}
handleToday() {
this.setState({
moment: moment(),
});
}
handleEventMouseOver(target, eventData, day) {
console.log("event data", target.props.eventData.url);
this.setState({
});
}
handleEventMouseOut(target, eventData, day) {
this.setState({
});
}
handleEventClick(target, eventData, day) {
this.setState({
});
}
handleDayClick(target, day) {
this.setState({
});
}
getMomentFromDay(day) {
return moment().set({
'year': day.year,
'month': (day.month + 0) % 12,
'date': day.day,
});
}
getHumanDate() {
return [moment.months('MM', this.state.moment.month()), this.state.moment.year(), ].join(' ');
}
render() {
return (
<div style={styles}>
<Row className='topBar'>
<Col xs={6}>
<ButtonToolbar>
<Button onClick={this.handlePreviousMonth}><</Button>
<Button onClick={this.handleNextMonth}>></Button>
<Button onClick={this.handleToday}>Today</Button>
</ButtonToolbar>
</Col>
<Col xs={6}>
<div className='pull-right h2'>{this.getHumanDate()}</div>
</Col>
</Row>
<br />
<Row>
<Col xs={12}>
<EventCalendar
month={this.state.moment.month()}
year={this.state.moment.year()}
events={events}
onEventClick={this.handleEventClick}
onEventMouseOver={this.handleEventMouseOver}
onEventMouseOut={this.handleEventMouseOut}
onDayClick={this.handleDayClick}
maxEventSlots={0}
/>
</Col>
</Row>
</div>
);
}
}
export default CalendarDemo
const styles = {
position: 'relative',
};
What do I need to change here so that I will get a functional ponent?
Share Improve this question edited Mar 29, 2020 at 16:12 The Dead Man asked Feb 14, 2020 at 9:21 The Dead ManThe Dead Man 5,57632 gold badges125 silver badges226 bronze badges 3-
What do I need to change here Everything... But to be serious, you will have to create variables for all properties in state. Then whenever you call
setState
, you will have to call setter. – Rajesh Commented Mar 29, 2020 at 16:14 - 4 Are you asking for help to convert this one, specific class or for an automated way to convert many similar classes throughout your code? – jarmod Commented Mar 29, 2020 at 16:18
- @jarmod any method as long as it changes it to a functional ponent – The Dead Man Commented Mar 29, 2020 at 16:35
3 Answers
Reset to default 6 +250Every method has to be changed to const method = () => ...
, every lifecycle has to be changed to a useState/useEffect
, the render
should be be the return
value of the functional ponent.
import React, { Component, useState } from 'react'
import EventCalendar from '../App';
import moment from 'moment';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
import Button from 'react-bootstrap/Button';
import ButtonToolbar from 'react-bootstrap/ButtonToolbar';
const events =[
{
title: 'Womens History Month ',
start: '2020-03-02',
end: '2020-03-02',
//description: '',
url: 'dev91b558163211cf9d2e7d1efe6c3e32035973fdf9',
eventClasses: 'event1'
},
];
export const CalendarDemo = (props) => {
const [_moment, updateMoment] = useState(moment());
const handleNextMonth = () => {
updateMoment(_moment.add(1, "M").clone());
}
const handlePreviousMonth = () => {
updateMoment(_moment.subtract(1, "M").clone());
}
const handleToday = () => {
updateMoment(moment());
}
const handleEventMouseOver = (target, eventData, day) => {
console.log("event data", target.props.eventData.url);
}
const handleEventMouseOut = (target, eventData, day) => {
}
const handleEventClick = (target, eventData, data) => {
}
const handleDayClick = (target, day) => {
}
const getMomentFromDay = day => {
return moment().set({
'year': day.year,
'month': (day.month + 0) % 12,
'date': day.day,
});
}
const getHumanDate = () => {
return [moment.months('MM', _moment.month()), _moment.year(), ].join(' ');
}
return (
<div style={styles}>
<Row className='topBar'>
<Col xs={6}>
<ButtonToolbar>
<Button onClick={handlePreviousMonth}><</Button>
<Button onClick={handleNextMonth}>></Button>
<Button onClick={handleToday}>Today</Button>
</ButtonToolbar>
</Col>
<Col xs={6}>
<div className='pull-right h2'>{getHumanDate()}</div>
</Col>
</Row>
<br />
<Row>
<Col xs={12}>
<EventCalendar
month={_moment.month()}
year={_moment.year()}
events={events}
onEventClick={handleEventClick}
onEventMouseOver={handleEventMouseOver}
onEventMouseOut={handleEventMouseOut}
onDayClick={handleDayClick}
maxEventSlots={0}
/>
</Col>
</Row>
</div>
);
}
export default CalendarDemo
const styles = {
position: 'relative',
};
- convert every class method
func
to an inner function (either usingfunction func() {}
or usingconst func = () => {}
) - convert every attribute
attr
in your state to aconst [attr, setAttr] = useState()
call. Then replace every call tothis.state.attr
withattr
and every call ofthis.setState({attr: newValue})
withsetAttr(newValue)
- Keep your
render()
function mostly as-is, just remove the outer function, remove everythis.
prefix when referencing function and replace every reference tothis.state
as described above - (Not present in your example): Replace
ponentDidMount
withuseEffect
- Replace
class CalendarDemo extends Component
withfunction CalendarDemo()
(use arrow-syntax, if you like)
Notes:
this.state
bindings need to be converted touseState
hooks- You'll need to export a
function
instead ofClass
as thedefault export
- I didn't add the onHandleClick methods as they weren't supplied in the example.
import React, { useState, Component } from "react"
import EventCalendar from '../App';
import moment from 'moment';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
import Button from 'react-bootstrap/Button';
import ButtonToolbar from 'react-bootstrap/ButtonToolbar';
const events = [
{
title: 'Womens History Month ',
start: '2020-03-02',
end: '2020-03-02',
//description: '',
url: 'dev91b558163211cf9d2e7d1efe6c3e32035973fdf9',
eventClasses: 'event1'
},
];
const CalendarComponent = (props) => {
const [momentState, updateMoment] = useState(moment())
const handlePreviousMonth = () => updateMoment(moment().subtract(1, 'M'));
const handleNextMonth = () => updateMoment(moment().add(1, 'M'));
const handleToday = () => updateMoment(moment())
const getHumanDate = () => {
return [
moment.months('MM', momentState.month()),
momentState.year(),
].join(' ');
}
// todo
// const handleEventClick =
// const handleEventMouseOver =
// const handleEventMouseOut =
// const handleDayClick =
return (
<div >
<Row className='topBar'>
<Col xs={6}>
<ButtonToolbar>
<Button onClick={handlePreviousMonth}><</Button>
<Button onClick={handleNextMonth}>></Button>
<Button onClick={handleToday}>Today</Button>
</ButtonToolbar>
</Col>
<Col xs={6}>
<div className='pull-right h2'>{getHumanDate()}</div>
</Col>
</Row>
<br />
<Row>
<Col xs={12}>
<EventCalendar
month={momentState.month()}
year={momentState.year()}
events={events}
// onEventClick={handleEventClick}
// onEventMouseOver={handleEventMouseOver}
// onEventMouseOut={handleEventMouseOut}
// onDayClick={handleDayClick}
maxEventSlots={0}
/>
</Col>
</Row>
</div >
);
}
export default CalendarComponent