如何处理反应

时间:2017-11-30 16:06:36

标签: javascript reactjs

我对React很新。我有两个组件:TimePickerComponent和TimeDurationPickerComponent。

TimePickerComponent 通过props传递一个TimeString(字符串)(仅当初始数据存在时),并显示为“08:00”。代码:

class TimePickerComponent extends React.Component {
    _placeholder;
    _defaultTimeString;
    _timeString;
    _errorStatus;
    _classes;

    constructor({ placeholder, defaultTimeString, timeString, errorStatus, classes }) {
        super();
        this._placeholder = placeholder;
        this._defaultTimeString = defaultTimeString;
        this._timeString = timeString;
        this._errorStatus = errorStatus;
        this._classes = classes;
    }

    get Placeholder() {
        return this._placeholder;
    }

    get DefaultTimeString() {
        return this._defaultTimeString ? this._defaultTimeString : CONTROLS_CONSTANTS.DEFAULT_TIME_STRING;
    }

    get TimeString() {
        return this._timeString;
    }

    get ErrorStatus() {
        return this._errorStatus;
    }

    get Classes() {
        return this._classes;
    }

    render() {
        return <FormControl>
            <TextField error={this.ErrorStatus}
                label={this.Placeholder}
                defaultValue={this.TimeString ? this.TimeString : this.DefaultTimeString}
                className={this.Classes.layout}
                type="time"
                InputLabelProps={{
                    shrink: true
                }}
            />
        </FormControl>
    }
}

TimePickerComponent.propTypes = {
    placeholder: PropTypes.string.isRequired,
    defaultTimeString: PropTypes.string,
    timeString: PropTypes.string,
    errorStatus: PropTypes.bool
}

export default withStyles(styles)(TimePickerComponent);

TimeDurationPickerComponent 通过道具传递TimeInMinutes(数字)。但显示与TimePickerComponent(“08:00”)相同。代码:

class TimeDurationPickerComponent extends React.Component {
    _placeholder;
    _timeInMinutes;
    _classes;

    constructor({ placeholder, timeInMinutes, classes }) {
        super();
        this._placeholder = placeholder;
        this._timeInMinutes = timeInMinutes;
        this._classes = classes;
    }

    get Placeholder() {
        return this._placeholder;
    }

    get TimeInMinutes() {
        return this._timeInMinutes;
    }

    get Classes() {
        return this._classes;
    }

    get TimeString() {
        let timeFormat = CONTROLS_CONSTANTS.TIME_FORMATS.HOURS_MINUTES_COLON_SEPARATED;
        let duration = moment.duration({ minutes: this.TimeInMinutes });

        //https://github.com/moment/moment/issues/463
        return moment.utc(duration.asMilliseconds()).format(timeFormat);
    }

    render() {
        return <TimePickerComponent
            placeholder={this.Placeholder}
            timeString={this.TimeString}
            classes={this.Classes}
        />
    }
}

TimeDurationPickerComponent.propTypes = {
    placeholder: PropTypes.string.isRequired,
    timeInMinutes: PropTypes.number
}

export default TimeDurationPickerComponent;

为避免代码冗余,我在TimeDurationPickerComponent中重用了TimePickerComponent,只是在TimeString中转换TimeInMinutes,并通过props将其传递给TimePickerComponent。

我现在的问题:这是一个很好的做法,我是如何解决这个问题的,还是我应该使用HigherOrderComponent?或者我应该使用继承方法吗?哪种解决方案最好,为什么?

提前谢谢。

1 个答案:

答案 0 :(得分:4)

你在这里做的很可能。它也可以用更高阶的组件来完成,但是基于组合的方法就像你所获得的那样,没有任何性能问题,说实话,它可能比使用HOC更具可读性。

另一方面,你应该使用this.props和this.state来表示你的类属性。它们构建在React组件中,并且会导致组件在更改时自动重新呈现。

它还使您的代码更加简洁,例如您可以将第二个组件减少到这样的程度:

class TimeDurationPickerComponent extends React.Component {

    constructor(props) {
        super(props);
    }

    createTimeString() {
        let timeFormat = CONTROLS_CONSTANTS.TIME_FORMATS.HOURS_MINUTES_COLON_SEPARATED;
        let duration = moment.duration({ minutes: this.props.TimeInMinutes });

        //https://github.com/moment/moment/issues/463
        return moment.utc(duration.asMilliseconds()).format(timeFormat);
    }

    render() {
        return <TimePickerComponent
            placeholder={this.props.Placeholder}
            timeString={this.createTimeString()}
            classes={this.props.Classes}
        />
    }
}

使用流程的组件示例:

// @flow

import React from 'react';

import './css/ToggleButton.css';

type Props = {
  handleClick: Function;
  label: string;
};

type LocalState = {
  active: bool,
};

class ToggleButton extends React.Component<Props, LocalState> {
  clickHandler: () => void;

  constructor(props: Props) {
    super(props);

    this.state = {
      active: true,
    };

    this.clickHandler = this.clickHandler.bind(this);
  }

  clickHandler() {
    this.setState({ active: !this.state.active });
    this.props.handleClick();
  }

  render() {
    const buttonStyle = this.state.active ? 'toggle-btn-active' : 'toggle-btn-inactive';
    return (
      <button
        className={`toggle-btn ${buttonStyle}`}
        onClick={this.clickHandler}
      >{this.props.label}
      </button>
    );
  }
}

export default ToggleButton;