palnic
palnic

Reputation: 127

Setting parent's height and width based on child dimension

I need to set height and width of a View, based on height and width of his child. Is it possible?

I tried to use onLayout prop, but actually I didn't get the proper way to use it. Also, I was trying using measure method but refs are now deprecated on react-native 0.59.

import React, {Component} from 'react';
import {View, Text} from 'react-native'

export default class myClass extends Component{
    render(){
        return(
            <View style={styles.container}>
               <View style={{}}>   //HERE I WANNA SET width and height of his child
                 <View>
                   <Text>Hello<Text>
                   <Text>Hello<Text>
                   <Text>Hello<Text>
                 </View>
               </View>
            </View>
        )
    }

}

Upvotes: 4

Views: 2867

Answers (1)

Stuart Gough
Stuart Gough

Reputation: 1714

If you are using react with hooks (version 16.8 and above) this is done regularly through use of hooks. First create a useLayoutDimension hook like this:

import { useState, useCallback } from 'react'

export function useLayoutDimension() {
  const [dimension, setDimension] = useState(0)
  const layoutDimension = { width: 0, height: 0 }
  const onLayout = useCallback(({ nativeEvent }) => {
    layoutDimension.width = nativeEvent.layout.width
    layoutDimension.height = nativeEvent.layout.height
    if (dimension !== layoutDimension.width && layoutDimension.width > 0) {
      setDimension(layoutDimension)
    }
  }, [])

  return {
    dimension,
    onLayout,
  }
}

Then in the Child component do this:

import { useLayoutDimension } from 'app/hooks'

export const ChildComponent = (props) => {
  const { dimension, onLayout } = useLayoutDimension()

  useEffect(
    () => {
      props.getChildDimensions(dimension)
    },
    [dimension]
  )

  return (
    <View style={styles.ShadowWrapper} onLayout={onLayout}>
        {...content}
    </View>
  )
}

And in the Parent component you then set a piece of state to the dimension like this:

//...rest of the parent component
//Child below
<ChildComponent
    getChildDimensions={(dimensions) => {
        this.setState({
            dimensions: dimensions,
        })
    }}
/>

You can then set any other component in the parent component with the dimension state

<View style={{width: this.state.dimension.width, height: this.state.dimension.height}}

Note: This is using a combination of class and functional components (The child is functional and the parent is class). If you are not comfortable with these concepts this will help. useState is the hook way of using this.state and useEffect is a hook that is fired at specific state changes. If you are unfamiliar with this a brief read on hooks will help immensely.

PS: The first render will not have the dimensions as the state will need to be set. This is usually not noticeable however.

Upvotes: 1

Related Questions