Использование initialPos из состояния Reactjs - PullRequest
0 голосов
/ 13 января 2019

Я создаю компонент React с фиксированной шириной и изменяемой высотой. Проблема в том, что я получаю event.clientY и this.state.initialPos с непредсказуемыми значениями. Вот скрипка

А вот код компонента React

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import '../styles/cal-event-styles.css';

class CalEvent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isDragging: false,
      height: 40,
      text: this.props.text,
      color: this.props.color
    }
  }

  componentDidMount() {
    ReactDOM.findDOMNode(this).addEventListener('mousemove', this.resizePanel);
    ReactDOM.findDOMNode(this).addEventListener('mouseup', this.stopResize);
    ReactDOM.findDOMNode(this).addEventListener('mouseleave', this.stopResize);
  }

  resizePanel = (event) => {
    if (this.state.isDragging) {
//I tried to use event.clientY - this.state.initialPos but it doesn't work
      let delta = event.clientY + this.state.height;
      console.log("event.clentY " + event.clientY);
      console.log("this.state.initialPos " + this.state.initialPos);
      this.setState({height: delta});
    }
  }

  stopResize = () => {
    if (this.state.isDragging) {
      this.setState({
        isDragging: false,
      });
    }
    // height: this.getStep(this.state.height)
  }

  getStep = (height) => {
    return Math.floor(height / 50) * 50;
  }

  startResize = (event) => {
    this.setState({
      isDragging: true,
      initialPos: event.clientX
    });
  }

  formatText = () => {
    const { text, height } = this.state;
    return text.length > 10 && height <= 100 ? text.substring(0, 14) + "..." : text;
  }

  render(){
    const {color, text, height, isDragging, initialPos } = this.state;

    console.log("this.state.isDragging: " + isDragging);
    if (isDragging) {

      console.log("this.state.height: " + height);
      console.log("this.state.initialPos: " + initialPos);
    }
    return(
      <div className="cal-event" onMouseUp={() => this.stopResize()} style={{height: `${height}px`, background: color}}>
        <div className="cal-event-tile"><p>{this.formatText()}</p></div>
        <div className="resizer-height" onMouseDown={e => this.startResize(e)}></div>
      </div>
    )
  }
}

export default CalEvent;

1 Ответ

0 голосов
/ 13 января 2019

Я думаю, что в этой строке:

let delta = event.clientY + this.state.height

дельта не должна быть суммой этих значений, потому что вы изменяете размер по оси Y, и именно Y (в данном случае) должно определять новую высоту:

Я пробовал это в методе resizePanel, и, похоже, он работает:

this.setState({ height: event.clientY })

Проблема этого подхода заключается в том, что в этом случае верхняя позиция компонента равна почти 0, и поэтому он работает совершенно безобидно.

Если вам нужно, чтобы он работал независимо от того, где находится компонент на странице, вы должны вычислить delta как разницу между верхней позицией и event.clientY.

Для этого я бы сохранил абсолютную верхнюю позицию компонента в методе жизненного цикла componentDidMount:

componentDidMount() {
  const currentNode = ReactDOM.findDOMNode(this)
  currentNode.addEventListener('mousemove', this.resizePanel);
  currentNode.addEventListener('mouseup', this.stopResize);
  currentNode.addEventListener('mouseleave', this.stopResize);
  this.setState({ initialY: currentNode.getBoundingClientRect().top })
}

Тогда в обработчике события настройка свойства height будет:

this.setState(prevState => ({ height: event.clientY - prevState.initialY }))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...