RamAlx
RamAlx

Reputation: 7334

Converting a stateful component to stateless

i'm pretty new to react and redux and i'm having an issue here. It's mandatory to use only stateless components with containers whenever state handing is required. These two components are:

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;

As you can see the first component is wrapped inside the second component. I tried to convert the first component myself like this:

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

but as you can see i dont know how to handle the onclick event. Can someone help me to achieve this?

Upvotes: 2

Views: 1382

Answers (1)

Julien TASSIN
Julien TASSIN

Reputation: 5212

To turn your component in a stateless component, you must pass everything as properties of the component.

This will be your DayInput splitted into 2 components :

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,      
}

And this will be the root component (uncomplete and still statefull) :

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;

Upvotes: 2

Related Questions