Задать вопрос
RazerVG
@RazerVG
Full-stack

Как получить ширину и высоту ref?

В данный момент делаю это так:
import React, { Component } from 'react';

import ReactDOM from 'react-dom';

import './testMenu.css';

class testMenu extends Component {

    constructor(props) {
        super(props);

        this.state = {
            menu: [
                {
                    title: 'Пункт 1',
                    active: true
                },
                {
                    title: 'Пункт 2',
                    active: false
                },
                {
                    title: 'Пункт 3',
                    active: false
                }
            ]
        };

        this._menuItems = [];
        this._menuBlock = null;
    }

    shouldComponentUpdate(nextProps, nextState, nextContext) {
        if (this.state.menu != nextState.menu) {
            return true;
        }

        return false;
    }

    componentDidMount() {
        this.getStyleMenuBlock();
    }

    handlerClickItem = (indexClick) => {
        let menuItems = this.state.menu.slice();

        menuItems.map((item, indexItem) => {
            if (indexItem == indexClick) {
                item.active = true;
            } else {
                item.active = false;
            }
        });

        this.setState({
            menu: menuItems
        })
    };

    getStyleMenuBlock = () => {
        let menuItems = this.state.menu.slice(),
            activeIndex = 0;

        menuItems.map((item, index) => {
            if (item.active) {
                activeIndex = index;
            }
        });


        this._menuBlock.style.width = ReactDOM.findDOMNode(this._menuItems[activeIndex]).getBoundingClientRect().width + 'px';
        this._menuBlock.style.height = ReactDOM.findDOMNode(this._menuItems[activeIndex]).getBoundingClientRect().height + 'px';
    };

    render() {
        return (
            <div className='test-menu'>
                <ul className='test-menu__menu'>
                    <React.Fragment>
                        {
                            this.state.menu.map((item, index) =>
                                <li
                                    className={`test-menu__item ${ item.active ? 'test-menu__item_active' : '' }`}
                                    onClick={ () => this.handlerClickItem(index) }
                                    ref={ref => { this._menuItems[index] = ref; return true; }}
                                >{ item.title }</li>
                            )
                        }
                        <li
                            className='test-menu__block'
                            ref={ref => { this._menuBlock = ref }}
                        />
                    </React.Fragment>
                </ul>
            </div>
        )
    }
}
export default testMenu;


Как можно получить ее напрямую в render ?

getStyleMenuBlock = () => {
        let menuItems = this.state.menu.slice(),
            ativeIndex = 0;

        menuItems.map((item, index) => {
            if (item.active) {
                ativeIndex = index;
            }
        });

        return {
            height: ? (this._menuItems[activeIndex].?)
            width: ? (this._menuItems[activeIndex].?)
        }
    };

    render() {
        return (
            <div className='test-block'>
                <ul className='test-block__menu'>
                    <React.Fragment>
                        {
                            this.state.menu.map((item, index) =>
                                <li
                                    className={`test-block__item ${ item.active ? 'test-menu__item_active' : '' }`}
                                    onClick={ () => this.handlerClickItem(index) }
                                    ref={ref => { this._menuItems[index] = ref; return true; }}
                                >{ item.title }</li>
                            )
                        }
                        <li className='test-block__block' style={ this.getStyleMenuBlock() }></li>
                    </React.Fragment>
                </ul>
            </div>
        )
    }


В последнем варианте пробовал getBoundingClientRect().width не работает, clientHeight не работает.
  • Вопрос задан
  • 1382 просмотра
Подписаться 1 Простой Комментировать
Решения вопроса 1
rockon404
@rockon404 Куратор тега React
Frontend Developer
Как можно получить ее напрямую в render ?

Так делать нельзя. На момент первого вызова render целевые элементы еще не смонтированы.
Что вы вообще хотите сделать? Возможно, задачу можно решить более изящным путем.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
hzzzzl
@hzzzzl
getStyleMenuBlock = () => {

что делает this.state.menu.slice() , если this.state.menu это уже массив?

        let menuItems = this.state.menu.slice(),
            ativeIndex = 0;

        menuItems.map((item, index) => {
            if (item.active) {
                ativeIndex = index;
            }
        });

***

ativeIndex / activeIndex ?
если это опечатка, то в этом моменте кода вообще что-то есть в this._menuItems[activeIndex] , или undefined ?

***

        return {
            height: ? (this._menuItems[activeIndex].?)
            width: ? (this._menuItems[activeIndex].?)
        }
    };
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы