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

Converting a stateful component to stateless

我是 React 和 redux 的新手,我在这里遇到了问题。只要需要状态处理,就必须仅将无状态组件与容器一起使用。这两个组件是:

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 事件。有人可以帮我实现这个目标吗?

要将您的组件变成无状态组件,您必须将所有内容作为组件的属性传递。

这会将您的 DayInput 分成 2 个部分:

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;