最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Fast way to convert react class component to functional component? - Stack Overflow

programmeradmin0浏览0评论

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}>&lt;</Button>
                                <Button onClick={this.handleNextMonth}>&gt;</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}>&lt;</Button>
                                <Button onClick={this.handleNextMonth}>&gt;</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
Add a ment  | 

3 Answers 3

Reset to default 6 +250

Every 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}>&lt;</Button>
                            <Button onClick={handleNextMonth}>&gt;</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 using function func() {} or using const func = () => {})
  • convert every attribute attr in your state to a const [attr, setAttr] = useState() call. Then replace every call to this.state.attr with attr and every call of this.setState({attr: newValue}) with setAttr(newValue)
  • Keep your render() function mostly as-is, just remove the outer function, remove every this. prefix when referencing function and replace every reference to this.state as described above
  • (Not present in your example): Replace ponentDidMount with useEffect
  • Replace class CalendarDemo extends Component with function CalendarDemo() (use arrow-syntax, if you like)

Notes:

  • this.state bindings need to be converted to useState hooks
  • You'll need to export a function instead of Class as the default 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}>&lt;</Button>
            <Button onClick={handleNextMonth}>&gt;</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
发布评论

评论列表(0)

  1. 暂无评论