React / Redux: где разместить обработчики событий jQuery в компоненте, ожидающем асинхронные данные - PullRequest
0 голосов
/ 14 сентября 2018

Когда я читаю документы ReactJS, я понимаю, что лучший метод жизненного цикла для размещения вызовов с избыточным действием - это componentDidMount, но мне трудно выполнять какую-либо работу jquery в этом методе жизненного цикла:

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            isAsyncLoaded: false
        }
    }
    static getDerivedStateFromProps(nextProps, prevState) {
        let {getData} = nextProps.someData;
        let {hasSuccess, isLoading} = getData;

        if (!isLoading && hasSuccess) {
            return {
                isAsyncLoaded: true
            }
        } else {
            return {
                isAsyncLoaded: false
            }
        }

        return null;
    }
    componentDidMount() {
        this.props.getSomeData();
        $('p').css('color', 'red');
    }
    render() {
        if (!this.state.isAsyncLoaded) return null;
        return (
            <p>{this.props.someData.data}</p>
        )
    }
}

function mapStateToProps(state) {
    return {
        someData: state.someData
    }
}

export default connect(mapStateToProps, {getSomeData})(App);

Здесьчасть jquery $('p').css('color', 'red'); не находит элемент <p>, потому что isAsyncLoaded не соответствует действительности и функция render возвращает null.

Мой вопрос заключается в том, как решить эту проблему, не вводяконтейнер-представление, (родитель-дочерний) отношение компонента к моему приложению?

Ответы [ 2 ]

0 голосов
/ 14 сентября 2018

Применить код JQuery в componentDidUpdate()

componentDidUpdate(prevProps, prevState) {
  // execute code only when at the moment when async code is first rendered
  if (prevState.isAsyncLoaded === false && this.state.isAsyncLoaded === true) {
    // Do your jQuery stuff here
    $(this.mountPoint).find(...);
  }
}

демо-версия: https://stackblitz.com/edit/react-ee57nm

0 голосов
/ 14 сентября 2018

Еще несколько замечаний, прежде чем я углублюсь в это: Использование обработчиков событий, таких как jQuery, обычно является антипаттерном в React.Это может вызвать непреднамеренные побочные эффекты для вашей DOM, которые в идеале должны обрабатываться полностью через управляемые компоненты в реагировать.

Если вам нужно использовать jQuery (для быстрого / грязного плагина или тому подобного), ярекомендую использовать отдельный компонент.Когда этот компонент монтируется, он запускает событие componentDidMount, которое вы можете подключить и запустить свой код jQuery:

class MyJqueryComponent extends React.Component {
    constructor(props) {
        super(props);
        this.mountPoint = React.createRef();
    }
    componentDidMount() {
        // Do your jQuery stuff here
        $(this.mountPoint).find(...);
    }
    render() {
        return (
            <p ref={this.mountPoint}>{this.props.data}</p>
        );
    }
}
class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            isAsyncLoaded: false
        }
    }
    static getDerivedStateFromProps(nextProps, prevState) {
        let {getData} = nextProps.someData;
        let {hasSuccess, isLoading} = getData;

        if (!isLoading && hasSuccess) {
            return {
                isAsyncLoaded: true
            }
        } else {
            return {
                isAsyncLoaded: false
            }
        }

        return null;
    }
    componentDidMount() {
        this.props.getSomeData();
        $('p').css('color', 'red');
    }
    render() {
        if (!this.state.isAsyncLoaded) return null;
        return (
            <p><MyJqueryComponent data={this.props.someData.data} /></p>
        )
    }
}

function mapStateToProps(state) {
    return {
        someData: state.someData
    }
}

export default connect(mapStateToProps, {getSomeData})(App);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...