Search code examples
javascriptreactjsreact-nativeuser-interfacescrollview

Scrollview not scrolling when using flex-start and flex-end


I'm using flexbox with my scrollview in react native and something about how it works is messing up the scrolling, it won't scroll. but if i remove all elements using flex-start, it seems to start scrolling, and i can't tell why

I've went through multiple other stackoverflow questions and none of them have worked, i'm at my wits end here

Components:

class UserMessage extends Component{
  render(){
    return(
      <View style={styles.userMessage}>
        <Text style={styles.userText}>{this.props.text}</Text>
      </View>
    )
  }
}
class OtherMessage extends Component{
  render(){
    return(
      <View style={styles.otherMessage}>
          <Text style={styles.otherText}>{this.props.text}</Text>
      </View>
    )
  }
}

main component:

export default class MessagingMain extends Component {
  constructor(props){
    super(props);
    this._scrollview = React.createRef();
  }
  componentDidMount(){
    this._scrollview.current.scrollToEnd();
  }

  render(){
    return (
      <View style={styles.container}>
        <ScrollView ref={this._scrollview} contentContainerStyle={styles.scrolltainer}>
        <StatusBar hidden />
          <UserMessage text="haha" />
          <UserMessage text="haha wow this is so fun writing overly long messages with half an ounce of meaning really brings meaning to my short, sad, life, where i have no other meaning other than making this here messaging app where i need to write overly long placeholder text" />
          <OtherMessage text="epic gamer moment" />
          <UserMessage text="why is this cut off :(" />
          <UserMessage text=":(((((" />
          <OtherMessage text="hey man fuck off" />
          <UserMessage text=":(((((" />
          <UserMessage text=":(((((" />
          <OtherMessage text=":(((((" />
          <UserMessage text=":(((((" />
          <OtherMessage text=":(((((" />
          <UserMessage text=":(((((" />
          <OtherMessage text=":(((((" />
          <UserMessage text=":(((((" />
          <UserMessage text=":(((((" />
          <OtherMessage text=":(((((" />
          <UserMessage text=":(((((" />
          <OtherMessage text=":(((((" />
          <UserMessage text=":(((((" />
          <OtherMessage text=":(((((" />
          </ScrollView>
      </View>

    );
  }
}

styles:

const styles = StyleSheet.create({
  input: {
    backgroundColor: "#222222",
    height:"10%",
  },
  container: {
    backgroundColor: "#121212",
    flexGrow: 0,
    justifyContent: "space-between",
    flexDirection:'row',
  },
  scrolltainer:{
    //height:"90%",
  },
  userMessage: {
    backgroundColor: "#c3073f",
    minWidth: "20%",
    maxWidth: "52%",
    alignSelf: 'flex-end',
    margin: "5%",
    minHeight: "5%",
    borderRadius: 11,
    borderBottomRightRadius: 1,
    marginTop: "1%",
    marginBottom: "1%",
  },
  userText: {
    margin: "8%"

  },
  topBar: {
    height:"10%",
  },
  otherMessage: {
    backgroundColor: "#b3b3b3",
    minWidth: "20%",
    maxWidth: "52%",
    alignSelf: 'flex-start',
    margin: "5%",
    minHeight: "5%",
    borderRadius: 11,
    borderBottomLeftRadius: 1,
    marginTop: "1%",
    marginBottom: "1%",
  },
  otherText: {
    margin: "8%"

  },
});

Solution

  • This is a notorious one. Try updating

    scrolltainer:{
        //height:"90%",
      }
    

    to

    scrolltainer:{
        flexGrow: 1
      }
    

    and then read this article

    It goes in to depth about the differences between CSS flexbox (where presumably most of our expectations for behavior originate) and React Native flexbox-- specifically that React Native interprets flex: 1 as the CSS equivalent:

    flex-grow: 1
    flex-shrink: 1
    flex-basis: 0
    

    It's also worth noting that a ScrollView can't really be treated the same as a View wrapping a bunch of repeated content. There are enough hairy internals inherited from FlatList down to Android native List class to obscure any relationship the component has to a View.