ddimonn8080
@ddimonn8080

Почему jQuery не находит елемент в componentDidMount()?

Здравствуйте, в componentDidMount делаю асинхронный запрос но jQuery не видит элемент DOM дерева.
components/pages/VideotipsPage/VideotipsPage.jsx

import React, {Component} from 'react';
import Breadcrumbs from '../../../helpers/breadcrumbs';
import Preloader from '../../../helpers/preloader';
import {Route} from 'react-router-dom';
import ErrorPage from '../ErrorPage';
import videotipSinglePagePopupInit from './videotipSinglePageMagnificPopupInit';
import $ from 'jquery';



class VideotipSinglePage extends Component {
    constructor(props){
        super(props);
        this.state = {
            videotipSlug: this.props.match.params.videotip,
        };
    }

    componentDidMount() {
        const {setSingleVideotip} = this.props;
        const {videotipSlug} = this.state;
        setSingleVideotip(videotipSlug);

        this.$el = $('.movietiphome_single__inner');
        videotipSinglePagePopupInit(this.$el);
    }

    render(){

        console.log( 'this.$el inside of render', this.$el );

        const {videotipSingle: {title, video, image}, isVideotipSingleLoading, isVideotipSingleReady, videotipSingleError} = this.props;

        if (videotipSingleError === 404) {
            return <Route component={ErrorPage} />
        }

        if (isVideotipSingleLoading) {
            return <Preloader />
        }

        if (!isVideotipSingleReady) {
            return null;
        }

        return (
            <React.Fragment>
                <div className="container">
                    <div className="row">
                        <div className="col-xs-12">
                            <Breadcrumbs />
                        </div>
                    </div>
                </div>
                <div className="movietiphome_single">
                    <div className="container movietiphome_single__titleContainer">
                        <div className="row movietiphome_single__titleRow">
                            <div className="col-xs-12 movietiphome_single__titleCol">
                                <div className="movietiphome_single__title home__sectionTitle">
                                    {title}
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <div className="container movietiphome_single__container">
                    <div className="row movietiphome_single__row">
                        <div className="col-xs-12 movietiphome_single__col">
                            <div className="movietiphome_single__inner">
                                <div className="movietiphome_single__item">
                                    <a href={video} title={title} className="movietiphome_single__link">
                                        <img src={image} alt={title} className="movietiphome_single__img" />
                                        <span className="movietiphome_single__play"></span>
                                    </a>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </React.Fragment>
        );
    }
}

export default VideotipSinglePage;


containers/pages/VideotipsPage/VideotipSinglePage.js

import {connect} from 'react-redux';
import VideotipSinglePage from '../../../components/pages/VideotipsPage/VideotipSinglePage';
import {setSingleVideotip} from '../../../actions/videotips';


const mapStateToProps = ({videotips: {videotipSingle, isVideotipSingleLoading, isVideotipSingleReady, videotipSingleError}}) => ({
    videotipSingle,
    isVideotipSingleLoading,
    isVideotipSingleReady,
    videotipSingleError
});

const mapDispatchToProps = dispatch => ({
    setSingleVideotip: slug => dispatch(setSingleVideotip(slug)),
});

export default connect(mapStateToProps, mapDispatchToProps)(VideotipSinglePage);

components/pages/VideotipsPage/videotipSinglePageMagnificPopupInit.js

export default function videotipSinglePagePopupInit($elem){
    console.log( '$elem inside function', $elem );

    $elem.each(function() {
        $(this).magnificPopup({
            type:'image',
            removalDelay: 500,
            mainClass: 'mfp-fade popup_inline',
            showCloseBtn: true,
            closeMarkup: '<div class="mfp-close">&times;</div>',
            closeBtnInside: true,
            closeOnContentClick: false,
            closeOnBgClick: true,
            alignTop: false,
            fixedContentPos: true,
            callbacks: {
                open: function() {
                    var headerHeight = $('.header__top').innerHeight();
                    $('.mfp-content').css({
                        'marginTop': headerHeight,
                    });

                    var mp = $.magnificPopup.instance,
                        t = $(mp.currItem.el[0]);

                    var $imgVideo = $(this.wrap[0]).find('img.mfp-img'),
                        $dataVideo = $(this.currItem.el).parent('.movietiphome_single__link').attr('href');

                    $imgVideo.addClass('has__video').attr('data-video', $dataVideo);

                    $imgVideo.parent('figure').append('<div class="movietiphome__play"></div>');
                    $('.mfp-content .movietiphome__play').click();
                },
                close: function() {

                },
                beforeOpen: function() {
                    var $triggerEl = $(this.st.el),
                        newClass = 'movietiphome__gallery';
                    this.st.mainClass = this.st.mainClass + ' ' + newClass;

                    this.st.image.markup = this.st.image.markup.replace('mfp-figure', 'mfp-figure mfp-with-anim');
                },
                elementParse: function(item) {
                    item.src = item.el.parent('.movietiphome_single__link').find('img').attr('src');
                },
                markupParse: function(template, values, item) {
                    values.title = item.el.parent('.movietiphome_single__link').attr('title');
                },
                change: function(){
                    var mp = $.magnificPopup.instance,
                        t = $(mp.currItem.el[0]);

                    var $imgVideo = $(this.wrap[0]).find('img.mfp-img'),
                        $dataVideo = $(this.currItem.el).attr('href');
                    $imgVideo.addClass('has__video').attr('data-video', $dataVideo);
                }
            },
            gallery: {
                enabled:false,
                navigateByImgClick: false,
            },
            delegate: '.movietiphome_single__play',
        });
    });
}

actions/videotips.js

import {
    SET_VIDEOTIPS,
    SET_VIDEOTIPS_SUCCEEDED,
    SET_VIDEOTIPS_FAILED,

    SET_VIDEOTIP_SINGLE,
    SET_VIDEOTIP_SINGLE_SUCCEEDED,
    SET_VIDEOTIP_SINGLE_FAILED,
} from '../actions/types/videotips-types';

export const setAllVideotips = () => {
    return async dispatch => {
        dispatch({type: SET_VIDEOTIPS});
        axios.get('/api/videotips').then(({data: videotips}) => {
            dispatch({type: SET_VIDEOTIPS_SUCCEEDED, payload: videotips});
        }).catch(err => {
            dispatch({type: SET_VIDEOTIPS_FAILED, payload: err});
        });
    };
};

export const setSingleVideotip = (slug) => {
    return async dispatch => {
        dispatch({type: SET_VIDEOTIP_SINGLE});
        axios.get(`/api/videotips/${slug}`).then(data => {
            const {videotip} = data.data;
            if (videotip) {
                dispatch({type: SET_VIDEOTIP_SINGLE_SUCCEEDED, payload: videotip});
            } else {
                dispatch({type: SET_VIDEOTIP_SINGLE_FAILED, payload: 404});
            }
        }).catch(err => {
            dispatch({type: SET_VIDEOTIP_SINGLE_FAILED, payload: 404});
        });
    };
};


Я понимаю что мне нужно вызвать
this.$el = $('.movietiphome_single__inner');
        videotipSinglePagePopupInit(this.$el);
после setSingleVideotip(videotipSlug); асинхронно, но как это сделать пока не понял.
Что скажете?

Спасибо.
  • Вопрос задан
  • 74 просмотра
Решения вопроса 1
rockon404
@rockon404 Куратор тега React
Frontend Developer
Почему jQuery не находит елемент в componentDidMount()

Потому что в момент вызова вы показываете Preloader или null.

Не стоит использовать JQuery в React разработке.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы