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

标签 javascript reactjs stateless stateful

我对 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;

关于javascript - 将有状态组件转换为无状态组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43834099/

相关文章:

javascript - Stateful 和 Functional 无状态组件

authentication - 使用无状态(=无 session )身份验证时需要 CSRF token 吗?

javascript - 如何让二维码阅读器识别我生成的二维码?

javascript - ECMAScript 6 中的原型(prototype)链

reactjs - 类型 'hot' .ts(2339) 上不存在属性 'NodeModule'

javascript - 如何摆脱控制台警告 "enableRowSelect has been deprecated... Please use rowSelection instead."“

java - 多线程(无状态类)

javascript - 通过 Javascript 访问我的整个浏览历史

javascript - 修复了滚动停止在 div 上的侧边栏

javascript - jsx 和 React 中的动态标签名称不传递 props