Как получить ширину и высоту 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 не работает.
  • Вопрос задан
  • 1281 просмотр
Решения вопроса 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].?)
        }
    };
Ответ написан
Ваш ответ на вопрос

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

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