javascript - 如何在 react 中处理两个相似的组件

标签 javascript reactjs

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

TimePickerComponent 通过 props 传递一个 TimeString(string)(仅当初始数据存在时)并将其显示为“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 通过 props 传递 TimeInMinutes(number) 。但显示与 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,只将 TimeInMinutes 转换为 TimeString 并通过 props 将其传递给 TimePickerComponent。

我现在的问题:这是我解决这个问题的好习惯吗?或者我应该使用 HigherOrderComponent 来解决这个问题?或者我应该为此使用继承方法?哪种解决方案最好,为什么?

提前谢谢您。

最佳答案

您在这里所做的可能没问题。它也可以使用更高阶的组件来完成,但是像您所拥有的基于组合的方法不会有任何性能问题,而且说实话,它可能比使用 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;

关于javascript - 如何在 react 中处理两个相似的组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47577696/

相关文章:

javascript - 在您的网站上载自定义字体

javascript - 将 jQuery 的 data() 与 Mustache.js 模板结合使用

javascript - 显示包含日期和其他记录的表

reactjs - 如何代码拆分 webpack 的 vendor block ?

javascript - 强制 Webpack 在 react-app bundle 中使用 ES6 语法

javascript - 网络工具包 : How to determine what elements are under a touch while dragging an animating div

javascript - 正则表达式字符串替换,同时保留原始换行符

javascript - React - 获取文本区域的值?

javascript - react 表事件

javascript - 不同类别的状态变化(不 react )