fadeOut нативными средствами React с выполнением логики по завершению

165
25 ноября 2018, 02:10

Есть, скажем, такая кнопка:

import React from 'react';
import $ from 'jquery';
class LoggingButton extends React.Component {
  handleClick = () => {
    $('#div-welcome').fadeOut(400, () => {
      // что-то нехорошее делаем
    });
  };
  render() {
    return (
      <button onClick={this.handleClick}  id="connect-button" className="default-button" >
        <span>Connect</span>
        <span id="loader"/>
      </button>
    );
  }
}
export default LoggingButton

Но для анимации используется jQuery, что совсем не React-way. Как сделать эту анимацию нативными средствами React'а с выполнением какой-то логики по завершению?

Чтобы работало и на нативных мобильных браузерах.

Answer 1

Про нативные средства React для анимаций ничего не знаю, но fadeOut тоже сойдет. Если его использовать правильно.

Во-первых, нельзя чтобы одним и тем же стилем управляли одновременно и React, и JQuery - а именно так сейчас и происходит. Вы делаете элементу fadeOut, но никогда не делаете ему fadeIn...

Во-вторых, ваш компонент с какого-то перепугу управляет совершенно левым элементом страницы который не он создавал. Это нарушает принцип изолированных компонентов, и ведет к потенциальным багам. Вместо этого следовало бы вызвать внешний обработчик, который изменит свойства отвечающего за анимацию компонента.

Ну и в-третьих, в идеологии React все переходы между состояниями UI должны делаться через изменение props, state или хотя бы через forceUpdate, но никак не в обработчике события.

Получается как-то так:

class DivWelcome extends React.Component {
    render() { ... }
    componentDidUpdate(prevProps) {
        const $this = $(ReactDOM.findDOMNode(this));
        if (this.props.visible && !prevProps.visible)
            $this.fadeIn();
        else if (!this.props.visible && prevProps.visible)
            $this.fadeOut();
    }
    componentDidMount() {
        const $this = $(ReactDOM.findDOMNode(this));
        if (this.props.visible)
            $this.show(); // или fadeIn, зависит от того что нужно получить
        else if (!this.props.visible)
            $this.hide(); // или fadeOut, зависит от того что нужно получить
    }
    componentWillUnmount() {
        const $this = $(ReactDOM.findDOMNode(this));
        $this.stop();
    }
}
class LoggingButton extends React.Component {
  render() {
    return (
      <button onClick={this.props.handleClick} className="default-button">
        <span>Connect</span>
        <span/>
      </button>
    );
  }
}
class App extends React.Component {
    constructor() {
        this.state = { welcomeVisible: true };
    }
    handleClick = () => setState({ welcomeVisible: false });
    render() {
        return [
            <DivWelcome visible={this.state.welcomeVisible} />,
            <LoggingButton handleClick={this.handleClick} />,
        ]
    }
}

PS код не проверял, и вообще я на реакте никогда не писал, так что относитесь к ответу с осторожностью

READ ALSO
Как реализовать анимацию CSS

Как реализовать анимацию CSS

При клике на кнопку 'добавить в корзину',как я понял копия картинки улетает в корзину и исчезаетВот пример

176
Рекурсивный обход дерева в jQuery

Рекурсивный обход дерева в jQuery

Не получается подняться вверх по дереву, хотя, на мой взгляд, всё вроде правильно

190
Вытащить значение title в label средствами jquery

Вытащить значение title в label средствами jquery

Есть блоки кода, подобные того что нижеС радиокнопки при клике нужно вытащить значение title внутреннего label(title="Серый") и вывести его в html

142
Выбор инструмента

Выбор инструмента

Стоит цель для самообразования, загрузить картинку на файлообменник без API Просто закинуть файл через форму и получить ссылку

158