2016-06-18 2 views
13

Предположим, что компонент должен знать свой размер до его рендеринга. Насколько мне известно, я могу это сделать: визуализировать компонент, в компонентеDidMount получить узел DOM и извлечь из него размер, обновить состояние с этим размером, а затем снова выполнить рендеринг (не затрудняет работу с прослушивателями событий, которые я бы подключил к событие изменения размера окна, позволяет предположить, что окно не изменяет размер) Это работает, но кажется грязным, первый рендер - это просто трата ресурсов, я хочу знать размер элемента (или его контейнера) до его рендеринга. Я знаю большую часть время, когда элемент сам объявляет размер, но есть ситуации, когда родительский элемент объявляет размер, и мой случай является одной из этих ситуаций. Итак, чтобы подвести итог, есть ли способ доступа к родительскому элементу реагирующего компонента до его рендеринга (в компонентеWillMount)?Реагировать: знать размер элемента до его рендеринга

P.S. Я знаю, как реагировать на изменения, но мне нужно более простое решение, для которого не нужны внешние плагины. Я просто хочу знать, возможно ли получить доступ к родительскому узлу в компонентеWillMount в ответ или нет.

ответ

16

Ответ: нет, но, пожалуйста, прочитайте идеи о том, как справиться.

Если элемент DOM не существует, вы не можете найти его размеры. Элемент DOM не существует до тех пор, пока не будет выполнен первый рендер для каждого компонента. Вы не можете ничего знать об этом элементе DOM или его родителе до тех пор, пока не будет вызван компонент componentDidMount().

Обратите внимание также на порядок отображения компонентов. При первоначальном рендеринге дерева/цепи компонентов дочерний componentDidMount() будет вызываться перед родительским componentDidMount()! Вот снимок из бревен из вложенного дерева меню:

(MenuItemSubmenu:handleRefSet)   appMenu:2.2.5.4 handleRefSet() 
(MenuItemSubmenu:componentDidMount)  appMenu:2.2.5.4 componentDidMount() 
(MenuPane:handleRefSet)     appMenu:2.2.5 handleRefSet() 
(MenuPane:componentDidMount)   appMenu:2.2.5 componentDidMount() 
(MenuItemSubmenu:handleRefSet)   appMenu:2.2.5 handleRefSet() 
(MenuItemSubmenu:componentDidMount)  appMenu:2.2.5 componentDidMount() 
(MenuPane:handleRefSet)     appMenu:2.2 handleRefSet() 
(MenuPane:componentDidMount)   appMenu:2.2 componentDidMount() 
(MenuItemSubmenu:handleRefSet)   appMenu:2.2 handleRefSet() 
(MenuItemSubmenu:componentDidMount)  appMenu:2.2 componentDidMount() 

componentDidMount() для дочернего элемента 2.2.5.4 вызывается перед тем, что для его родительского элемента 2.2.5. Из этого можно видеть, что родительский компонент не может знать свой собственный элемент DOM до тех пор, пока вся обработка для ребенка не будет завершена. Хм, ничего себе!

Однако, выполнив ваш вопрос, я добавил несколько протоколов к методу componentDidMount() компонента. Я зарегистрировал this.refToOurDom.parentElement и обнаружил, что он был определен и выглядел хорошо!

(MenuItemSubmenu:handleRefSet) appMenu:2.2.5.4 parent dims: height 76 width 127 

Таким образом, ответ на ваш вопрос, нет, ваш DOM элемент еще не существует в componentWillMount() и родитель не существует ни на первоначальный визуализации. Вы должны подождать, пока не будет вызвано componentDidMount(), прежде чем обнаруживать размеры любого компонента.

Но обратите внимание на трюк, который использует react-dimensions. Возможно, это даст вам идеи, как структурировать ваш код.

В своем render() методе react-dimensionsможет не отображаться прилагаемый компонент! При первоначальном рендеринге он отображает только содержащий < div>. Только после того, как его componentDidMount() вызывается и он обнаруживает размеры родителя, только тогда будет отображать прилагаемый компонент, и теперь, поставляя размеры родителя.

Так что другой ответ просто не отображает содержимое вашего компонента, пока вы не узнаете размеры родителя. Использование react-dimensions делает это легко, потому что вы даже не отображаются до тех пор, пока размеры не будут известны.Но вы также можете делать то же самое, получая ссылку в своем componentDidMount() и захватывая размеры, и просто помещаете if(){} вокруг визуализации реального содержимого вашего компонента, пока не узнаете размеры. (Вам нужно, по крайней мере, внешний < div>, чтобы получить свой собственный реф.)

+0

Спасибо, да, это то, что я получил, прочитав код с измерением размеров. Я думал, что родительский элемент корневого элемента (который не отображается в реакции) доступен до компонента componentWillMount, и, как вы ясно ответили, он недоступен. Спасибо за подробную информацию. – Sassan

Смежные вопросы