将有状态组件转换为无状态组件

时间:2017-05-07 16:48:24

标签: javascript reactjs stateless stateful

我很反应和还原,我在这里遇到问题。只要需要进行状态处理,就必须在容器中仅使用无状态组件。这两个组成部分是:

import React from 'react';
import DatePicker from '../DatePicker';

class DayInput extends React.Component { // eslint-disable-line react/prefer-stateless-function
  constructor(props) {
    super(props);

    this.state = {
      dateValue: new Date(),
      activeDateWidget: false,
    };
  }

  changeDate(date) {
    this.setState({
      dateValue: date,
    });
  }

  changeActiveDateWidget(e) {
    e.stopPropagation();
    this.setState({
      activeDateWidget: !this.state.activeDateWidget,
    });
  }

  render() {
    const { input, meta } = this.props;
    const { dateValue, activeDateWidget } = this.state;
    return (
      <div>
        <input
          {...input}
          className="form-control"
          type="text"
          value={dateValue}
          onClick={this.changeActiveDateWidget}
          // onBlur={this.changeActiveDateWidget}
        />

        {activeDateWidget ? (
          <div>
            <DatePicker
              changeActiveDateWidget={this.changeActiveDateWidget}
              changeDate={this.changeDate}
              dateValue={dateValue}
            />
          </div>
        ) : (
          <div />
        )}
      </div>
    );
  }
}
export default DayInput;

import React from 'react';
import 'react-day-picker/lib/style.css';
import DayPicker, { DateUtils } from 'react-day-picker';

class DatePicker extends React.Component { // eslint-disable-line react/prefer-stateless-function
  constructor(props) {
    super(props);
    this.state = {
      selectedDay: new Date(),
    };
  }

  componentDidMount() {
    if (this.input) {
      this.input.focus();
    }
  }

  handleDayClick(e, day, { disabled }) {
    e.stopPropagation();
    if (disabled) {
      return;
    }
    this.setState({ selectedDay: day }, () => {
      this.props.changeDate(day);
      this.props.changeActiveDateWidget();
    });
  }

  focusThisComponent(e) {
    if (e) {
      this.input = e;
    }
  }

  render() {
    const { changeActiveDateWidget } = this.props;
    const { selectedDay } = this.state;
    return (
      <div
        ref={this.focusThisComponent}
        tabIndex="1"
      >
        <DayPicker
          id="THISTHING"
          initialMonth={selectedDay}
          selectedDays={day => DateUtils.isSameDay(selectedDay, day)}
          onDayClick={this.handleDayClick}
        />
      </div>
    );
  }
}

export default DatePicker;

如您所见,第一个组件包含在第二个组件中。我试图像这样自己转换第一个组件:

const DayInput = props => {
  <input
    {...props.input}
    type="text"
    value= {new Date()}
    onClick={()=>??}
   />
}

但是你可以看到我不知道如何处理onclick事件。有人可以帮助我实现这个目标吗?

1 个答案:

答案 0 :(得分:1)

要在无状态组件中转换组件,必须将所有内容作为组件的属性传递。

这将是您的DayInput分为两个组成部分:

const DayInputShow = props => {
  return (<input
    {...props.input}
    type="text"
    value= {props.value}
    onClick={(event)=>props.onClick()}
    />);
};

const DayInputEdit = props => {
  return (<DatePicker
    changeActiveDateWidget={props.changeActiveDateWidget}
    changeDate={props.onChange}
    dateValue={props.value}
  />);
};

DayInputShow.propTypes = {
  value: PropTypes.date,
  onClick: PropTypes.func,      
}

DayInputEdit.propTypes = {
  value: PropTypes.date,
  onChange: PropTypes.func,      
}

这将是根组件(未完成且仍然是有状态的):

class DatePicker extends React.Component { // eslint-disable-line react/prefer-stateless-function
  constructor(props) {
    super(props);
    this.state = {
      selectedDay: new Date(),
    };
  }

  componentDidMount() {
    if (this.input) {
      this.input.focus();
    }
  }

  handleDayClick(e, day, { disabled }) {
    e.stopPropagation();
    if (disabled) {
      return;
    }
    this.setState({ selectedDay: day }, () => {
      this.props.changeDate(day);
      this.props.changeActiveDateWidget();
    });
  }

  focusThisComponent(e) {
    if (e) {
      this.input = e;
    }
  }

  render() {
    const { changeActiveDateWidget } = this.props;
    const { selectedDay } = this.state;
    let dayPicker;
    if (this.input) {
      dayPicker = <DayPickerEdit
          value={this.state.selectedDay}
          onChange={(value) => {this.setState({selectedDay: value})}}
          selectedDays={day => DateUtils.isSameDay(selectedDay, day)}
          onDayClick={this.handleDayClick}
        />
    } else {
      dayPicker = <DayPickerShow
          value={this.state.selectedDay}
          ref={(input) => { this.inputRef = input; }} />
          onClick={() => {this.focusThisComponent(this.inputRef )}}
        />
    }
    return (
      <div
        ref={this.focusThisComponent}
        tabIndex="1"
      >
        {dayPicker }
      </div>
    );
  }
}

export default DatePicker;