Задать вопрос
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 не работает.
  • Вопрос задан
  • 1399 просмотров
Подписаться 1 Простой Комментировать
Решение пользователя Антон Спирин К ответам на вопрос (2)
rockon404
@rockon404 Куратор тега React
Frontend Developer
Как можно получить ее напрямую в render ?

Так делать нельзя. На момент первого вызова render целевые элементы еще не смонтированы.
Что вы вообще хотите сделать? Возможно, задачу можно решить более изящным путем.
Ответ написан