Как добавить событие прокрутки в компонент реакции

Я пытаюсь добавить событие onScroll в таблицу. Это то, что я пробовал:

componentDidMount() {
    ReactDOM.findDOMNode(this.refs.table).addEventListener('scroll', this.listenScrollEvent);
}

componentWillUnmount() {
    ReactDOM.findDOMNode(this.refs.table).removeEventListener('scroll', this.listenScrollEvent);
}

listenScrollEvent() {
    console.log('Scroll event detected!');
}

render() {
    return (
        <table ref="table">
           [...]
        </table>
    )
}

Я пробовал console.log(ReactDOM.findDOMNode(this.refs.table)), и я получаю правильный результат, но событие прокрутки никогда не запускается вообще. Я посмотрел здесь, но все еще не смог. Любая помощь была бы высоко оценена.

Ответ 1

Вам нужно связать это с элементом в контексте.

render() {
    return (
        <table ref="table" onScroll={this.listenScrollEvent.bind(this)}>
           [...]
        </table>
    )
}

Ответ 2

Вы можете использовать атрибут onScroll:

listenScrollEvent() {
    console.log('Scroll event detected!');
}

render() {
    return (
        <table onScroll={this.listenScrollEvent}>
           [...]
        </table>
    )
}

Вот пример: https://jsfiddle.net/81Lujabv/

Ответ 3

Я искал что-то подобное. Добавление прослушивателя событий в окно вместо ReactDom.findDOMNode работало для меня...

componentDidMount() {
    window.addEventListener('scroll', this.handleScrollToElement);
}

componentWillUnmount() {
    window.removeEventListener('scroll', this.handleScrollToElement);
}

handleScrollToElement(event) {
    console.log('Fired ' + event)
}

Ответ 4

Я нашел хорошее решение этой проблемы. Работает следующий фрагмент кода, где слушатель находится только в определенном классе /div: React версия 16.0.0

Сначала импортируйте ReactDOM, import ReactDOM from "react-dom";

Затем в class xyz extends Component раздел class xyz extends Component

  constructor(props) {
    super();
    this.state = {
        vPos : 0
    }
    this.listenScrollEvent = this.listenScrollEvent.bind(this);
  }

  componentDidMount() {
    ReactDOM.findDOMNode(this.refs.category_scroll).addEventListener('scroll', this.listenScrollEvent);
  }

  componentWillUnmount() {
      ReactDOM.findDOMNode(this.refs.category_scroll).removeEventListener('scroll', this.listenScrollEvent);
  }

  listenScrollEvent(event) {
    console.log('firee');
    this.setState({
        vPos: event.target.body.scrollTop
    });
  }

После вставки вышеуказанных функций в методе render(), как бы вы ни findDOMNode метод ref, вы можете сделать это, убедитесь, что то же имя входит и в findDOMNode, то есть findDOMNode(this.refs.category_scroll):

<div onScroll={this.listenScrollEvent} ref="category_scroll">
...
</div>

,

,

Если это горизонтальная прокрутка, то event.currentTarget.scrollTop работает в функции listenScrollEvent().

Ответ 5

в соответствии с документами React (https://reactjs.org/docs/handling-events.html),

События React называются с использованием camelCase, а не в нижнем регистре. Вы можете установить атрибуты, как вы делаете с чистым HTML.

HTML:

<div onclick="..." onscroll="...">
  ...
</div>

JSX:

<div onClick={...} onScroll={...}>
  ...
</div>

Вы должны создать элемент блока обертки, который имеет фиксированную высоту, чтобы включить прокрутку.

Ответ 6

Попробуйте, добавьте .bind(this) в this.listenScrollEvent, когда вы передадите его в addEventListener.

   componentDidMount() {
        ReactDOM.findDOMNode(this.refs.table).addEventListener('scroll', this.listenScrollEvent.bind(this));
    }

    componentWillUnmount() {
        ReactDOM.findDOMNode(this.refs.table).removeEventListener('scroll', this.listenScrollEvent.bind(this));
    }

    listenScrollEvent() {
        console.log('Scroll event detected!');
    }

    render() {
        return (
            <table ref="table">
               [...]
            </table>
        )
    }