Search code examples
react-nativeflexboxcomponentsreact-native-flexbox

Cannot change width and height of custom component in React-native?


I have a minimal custom stateless component like this:

const ViewBox = (props) => (
    <View style={ mainStyle : {backgroundColor: 'beige'} }>
        {props.children}
    </View>
)
export default ViewBox;

so I want to import and use it inside another component.

export default class Test extends React.Component {

render() {
    return (
        <View style={styles.containerView} >
            <ViewBox style={styles.mainBox}>
              <Text style={[styles.boxTitle, {color: '#8F468C'}]}>Lorem ipsum...</Text>
            </ViewBox>
        </View>
    );
    }
}

const styles = {    
  containerView: {
    flex: 1,
    marginTop: 50,
    alignItems: 'center',
    backgroundColor: 'brown',
  },
  mainBox: {
    flex: 1,
    width: 250,  //No effect ! ! !
    height: 250  //No effect ! ! !
  },
  boxTitle: {
    backgroundColor: 'pink',
    fontSize: 17,
    marginTop: 20
  }
};

Here we have at least 2 inexplicable facts:
1) and more important the width and height of the ViewBox (or every custom component you want to use here) is totally out of control! Assigning numeric size or Flex values has no effect and ViewBox keeps the minimum width/height needed to render the inner Text.

enter image description here

2) Removing the root View (so the ViewBox became the root) ViewBox continue ignoring any size, but now it fills all the space available.... WHY???

enter image description here

All mentioned behavoirs occurs using a custom View (ViewBox in this case), instead if replace it with a normal View all works as expected.
I guess to know enough flex and UI best practices for React-native, but such two cases are not well covered by docs. Hope somebody can surprise me!


Solution

  • This is actually how flexbox works:

    1. Flex containers come with flexShrink: 1 by default meaning that they will shrink to their contents. Adding flexShrink: 0 changes that. You may need to use minWidth and minHeight with that instead.

    2. The reason why it stretches is because there's nothing to tell it otherwise. Your container has the default alignItems: 'stretch' overwritten with alignItems: 'center' which shrinks its contents.

    Have a look at the example code on Snack: https://snack.expo.io/B1VdUma1M

    There's a really nice flexbox cheatsheet/playground that shows the behaviour at: https://yoksel.github.io/flex-cheatsheet/

    Bear in mind React Native's implementation is slightly different.