ReactJS中的空函数

时间:2017-12-27 00:55:23

标签: reactjs

我目前正在阅读"教程" (它真的只是代码)关于如何在ReactJS中制作日历,它包含许多空函数。您可以在下面找到代码:

var Calendar = React.createClass({
    calc: function (year, month) {},
    componentWillMount: function () {},
    componentDidMount: function () {},
    componentDidUpdate: function (prevProps, prevState) {},
    getPrev: function () {},
    getNext: function () {},
    selectDate: function (year, month, date, element) {},
    render: function () {
        return (
           //some code
        );
    }
});

var Header = React.createClass({
    render: function () {}
});

(资料来源:https://zinoui.com/blog/react-calendar-component

空函数表示什么?如果他们不做任何事情,他们怎么能有任何目的?为什么你还要包括他们?或者代码是不完整的?

3 个答案:

答案 0 :(得分:2)

在您提供的链接(https://zinoui.com/blog/react-calendar-component)中,作者可能只是忘了填写这些功能,

JSFiddle中,它们不是空的 - 我复制粘贴代码:

/**
 * React Calendar Component v0.1.1
 *
 * Copyright 2016, Dimitar Ivanov
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 */
var Calendar = React.createClass({
    displayName: 'Calendar',
    calc: function (year, month) {
        if (this.state.selectedElement) {
            if (this.state.selectedMonth != month || this.state.selectedYear != year) {
                this.state.selectedElement.classList.remove('r-selected');
            } else {
                this.state.selectedElement.classList.add('r-selected');
            }
        }
        return {
            firstOfMonth: new Date(year, month, 1),
            daysInMonth: new Date(year, month + 1, 0).getDate()
        };
    },
    componentWillMount: function () {
        this.setState(this.calc.call(null, this.state.year, this.state.month));
    },
    componentDidMount: function () {},
    componentDidUpdate: function (prevProps, prevState) {
        if (this.props.onSelect && prevState.selectedDt != this.state.selectedDt) {
            this.props.onSelect.call(this.getDOMNode(), this.state);
        }
    },
    getInitialState: function () {
        var date = new Date();
        return {
            year: date.getFullYear(),
            month: date.getMonth(),
            selectedYear: date.getFullYear(),
            selectedMonth: date.getMonth(),
            selectedDate: date.getDate(),
            selectedDt: new Date(date.getFullYear(), date.getMonth(), date.getDate()),
            startDay: 1,
            weekNumbers: false,
            minDate: this.props.minDate ? this.props.minDate : null,
            disablePast: this.props.disablePast ? this.props.disablePast : false,
            dayNames: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
            monthNames: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
            monthNamesFull: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
            firstOfMonth: null,
            daysInMonth: null
        };
    },
    getPrev: function () {
        var state = {};
        if (this.state.month > 0) {
            state.month = this.state.month - 1;
            state.year = this.state.year;
        } else {
            state.month = 11;
            state.year = this.state.year - 1;
        }
        Object.assign(state, this.calc.call(null, state.year, state.month));
        this.setState(state);
    },
    getNext: function () {
        var state = {};
        if (this.state.month < 11) {
            state.month = this.state.month + 1;
            state.year = this.state.year;
        } else {
            state.month = 0;
            state.year = this.state.year + 1;
        }
        Object.assign(state, this.calc.call(null, state.year, state.month));
        this.setState(state);
    },
    selectDate: function (year, month, date, element) {
        if (this.state.selectedElement) {
            this.state.selectedElement.classList.remove('r-selected');
        }
        element.target.classList.add('r-selected');
        this.setState({
            selectedYear: year,
            selectedMonth: month,
            selectedDate: date,
            selectedDt: new Date(year, month, date),
            selectedElement: element.target
        });
    },
    render: function () {
        return React.createElement(
            'div',
            { className: 'r-calendar' },
            React.createElement(
                'div',
                { className: 'r-inner' },
                React.createElement(Header, { monthNames: this.state.monthNamesFull, month: this.state.month, year: this.state.year, onPrev: this.getPrev, onNext: this.getNext }),
                React.createElement(WeekDays, { dayNames: this.state.dayNames, startDay: this.state.startDay, weekNumbers: this.state.weekNumbers }),
                React.createElement(MonthDates, { month: this.state.month, year: this.state.year, daysInMonth: this.state.daysInMonth, firstOfMonth: this.state.firstOfMonth, startDay: this.state.startDay, onSelect: this.selectDate, weekNumbers: this.state.weekNumbers, disablePast: this.state.disablePast, minDate: this.state.minDate })
            )
        );
    }
});

var Header = React.createClass({
    displayName: 'Header',

    render: function () {
        return React.createElement(
            'div',
            { className: 'r-row r-head' },
            React.createElement('div', { className: 'r-cell r-prev', onClick: this.props.onPrev.bind(this), role: 'button', tabIndex: '0' }),
            React.createElement(
                'div',
                { className: 'r-cell r-title' },
                this.props.monthNames[this.props.month],
                ' ',
                this.props.year
            ),
            React.createElement('div', { className: 'r-cell r-next', onClick: this.props.onNext.bind(this), role: 'button', tabIndex: '0' })
        );
    }
});

var WeekDays = React.createClass({
    displayName: 'WeekDays',

    render: function () {
        var that = this,
            haystack = Array.apply(null, { length: 7 }).map(Number.call, Number);
        return React.createElement(
            'div',
            { className: 'r-row r-weekdays' },
            (() => {
                if (that.props.weekNumbers) {
                    return React.createElement(
                        'div',
                        { className: 'r-cell r-weeknum' },
                        'wn'
                    );
                }
            })(),
            haystack.map(function (item, i) {
                return React.createElement(
                    'div',
                    { className: 'r-cell' },
                    that.props.dayNames[(that.props.startDay + i) % 7]
                );
            })
        );
    }
});

var MonthDates = React.createClass({
    displayName: 'MonthDates',

    statics: {
        year: new Date().getFullYear(),
        month: new Date().getMonth(),
        date: new Date().getDate(),
        today: new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate())
    },
    render: function () {
        var haystack,
            day,
            d,
            current,
            onClick,
            isDate,
            className,
            weekStack = Array.apply(null, { length: 7 }).map(Number.call, Number),
            that = this,
            startDay = this.props.firstOfMonth.getUTCDay(),
            first = this.props.firstOfMonth.getDay(),
            janOne = new Date(that.props.year, 0, 1),
            rows = 5;

        if (startDay == 5 && this.props.daysInMonth == 31 || startDay == 6 && this.props.daysInMonth > 29) {
            rows = 6;
        }

        className = rows === 6 ? 'r-dates' : 'r-dates r-fix';
        haystack = Array.apply(null, { length: rows }).map(Number.call, Number);
        day = this.props.startDay + 1 - first;
        while (day > 1) {
            day -= 7;
        }
        day -= 1;
        return React.createElement(
            'div',
            { className: className },
            haystack.map(function (item, i) {
                d = day + i * 7;
                return React.createElement(
                    'div',
                    { className: 'r-row' },
                    (() => {
                        if (that.props.weekNumbers) {
                            var wn = Math.ceil(((new Date(that.props.year, that.props.month, d) - janOne) / 86400000 + janOne.getDay() + 1) / 7);
                            return React.createElement(
                                'div',
                                { className: 'r-cell r-weeknum' },
                                wn
                            );
                        }
                    })(),
                    weekStack.map(function (item, i) {
                        d += 1;
                        isDate = d > 0 && d <= that.props.daysInMonth;

                        if (isDate) {
                            current = new Date(that.props.year, that.props.month, d);
                            className = current != that.constructor.today ? 'r-cell r-date' : 'r-cell r-date r-today';
                            if (that.props.disablePast && current < that.constructor.today) {
                                className += ' r-past';
                            } else if (that.props.minDate !== null && current < that.props.minDate) {
                                className += ' r-past';
                            }

                            if (/r-past/.test(className)) {
                                return React.createElement(
                                    'div',
                                    { className: className, role: 'button', tabIndex: '0' },
                                    d
                                );
                            }

                            return React.createElement(
                                'div',
                                { className: className, role: 'button', tabIndex: '0', onClick: that.props.onSelect.bind(that, that.props.year, that.props.month, d) },
                                d
                            );
                        }

                        return React.createElement('div', { className: 'r-cell' });
                    })
                );
            })
        );
    }
});

ReactDOM.render(React.createElement(Calendar, {
    //onSelect: function (state) {
    //console.log(this, state);
    //},
    //disablePast: true,
    //minDate: new Date(2016, 2, 28)
}), document.getElementById("calendar"));

答案 1 :(得分:2)

我不知道您所指的博文的作者的确切意图,但是,我可以给您一些关于React组件的方法的提示。

  1. React现在支持ES6类和纯函数来创建组件。基本上不推荐使用React.createClass,但不建议使用它。

  2. React组件,如果以ES6经典方式编写,则带有一些内置生命周期方法,例如componentDidMountcomponentDidUpdate等。它们也可以在其实例上使用自定义方法。在定义这些自定义方法(函数)时,您可能希望在组件的render方法中使用它们来将一些疯狂的东西渲染到DOM中。这样你最终会在你的render方法中调用这个函数,如果你在使用时没有将这些方法作为props传递给你的组件,它会抛出错误而JS会抱怨。 将空函数定义为默认道具可以帮助您绕过这些例外。

答案 2 :(得分:1)

您发布的代码中的许多空函数都是在React组件的函数中构建的。其中有些不是,所以我认为作者将其留空是出于其他原因 - 可能只是定义组件的签名等。

React组件具有生命周期&#39; - 基本上,这些函数决定了组件在应用程序使用期间在某些明确定义的点上将执行的操作。您可以阅读有关各个功能和整个生命周期here.

的更多信息

例如,componentDidMount将触发组件生效的第一时间 - 如果您想在该时间点执行某些操作,您可以将此逻辑放在此处。我喜欢将此视为document.onload

之类的组件版本

还有一些功能可以帮助您控制实际的生命周期 - shouldComponentUpdate,例如,让您在重新呈现自己时告诉您的组件。如果您决定在州/道具更改为foo时不想要启动新渲染,那么您可以将此逻辑放在此处。

这些函数在编写React组件时提供了很大的灵活性。在许多情况下,默认行为可以正常工作,但随着应用程序的增长和组件变得更加复杂,它们可能需要稍微进行一些自定义。

您可以阅读更多有关您可以使用的生命周期功能以及如何在文档中使用它们的信息,但希望这能让您了解它们为何会在那里使用。