FortuneCookie
FortuneCookie

Reputation: 1865

react-native FlatList scroll to bottom for chat app

I've made a chat app, and for rendering messages flatlist is used. But the problem is tried to scroll to the end of the screen every time the page is loaded, but it fails to do so. I've tried inverted props, but nothing happened, only the list got inverted.

Even played with ref to make it auto-scroll to the bottom, but nothing happened.

<FlatList
  ref="flatList"
  onContentSizeChange={() =>
    this.refs.flatList.scrollToEnd()}
  contentContainerStyle={{
    marginBottom:
      verticalScale(200)
  }}
  style={styles.list}
  data={this.state.messages}
/>

How to make it scroll to the bottom the screen or scroll to the last index of the message when rendered?

(UPDATE)

IT WAS AN ISSUE WITH THE <Content/> component i used which belongs to native-base . Upon removing and replacing it with a <View/> it works perfectly fine. Also, for chat based app the inverted prop in Flatlist is the way to implement in right way.

I've added the way i managed to scroll in the answer below. If you simply want your app to display the last item in the list and stays there, you can use inverted.

Upvotes: 1

Views: 10162

Answers (6)

Victoria
Victoria

Reputation: 1

 useEffect(()=> {
        setTimeout(() => {
          flatListRef.scrollToEnd();
        }, 500);
      },[]);
    
    <FlatList
      ref={(ref) => flatListRef = ref}
      showsVerticalScrollIndicator={false}
      data={dataMessages}
      renderItem={({ item, index }) => (
        <ChatMessagesItem
          item={item}
          index={index}
          dataLength = {dataMessages.length}
         />
      )}
    />

Upvotes: 0

Flagship1442
Flagship1442

Reputation: 1726

You should use ref like this:

    export default class MyAwesomeComponent extends React.Component {
      FlatListRef = null; // add a member to hold the flatlist ref
    
      render() {
        return (
          <FlatList
            ref={ref => (this.FlatListRef = ref)} // assign the flatlist's ref to your component's FlatListRef...
            onContentSizeChange={() => this.FlatListRef.scrollToEnd()} // scroll it
            contentContainerStyle={{marginBottom: verticalScale(200)}}
            style={styles.list}
            data={this.state.messages}
          />
        );
      }
    }

Upvotes: 5

AN German
AN German

Reputation: 791

prueba esto

return (
      <View style={{flex: 1}}>
        <KeyboardAvoidingView
          behavior="padding"
          style={styles.keyboard}
          keyboardVerticalOffset={height - 1000}>
          <FlatList
            ref={ref => (this.FlatListRef = ref)}
            onContentSizeChange={() => this.FlatListRef.scrollToEnd()} // scroll it
            // contentContainerStyle={{marginBottom: verticalScale(200)}}
            // keyboardShouldPersistTaps='always'
            style={styles.list}
            extraData={this.state}
            data={this.state.messages}
            keyExtractor={item => {
              return item.id;
            }}
            renderItem={e => this._renderItem(e)}
          />
          <View style={styles.input}>
            <TextInput
              // style={{flex: 1}}
              value={msg}
              placeholderTextColor="#000"
              onChangeText={msg => this.setState({msg: msg})}
              blurOnSubmit={false}
              onSubmitEditing={() => this.send()}
              placeholder="Escribe el mensaje"
              returnKeyType="send"
            />
          </View>
        </KeyboardAvoidingView>
      </View>
    );

Upvotes: 2

FortuneCookie
FortuneCookie

Reputation: 1865

Here is how i solved it:

export default class Test extends Component {
  constructor(props) {
    super(props);
  }
  componentDidMount() {
    setTimeout(() => {
      this.FlatListRef.scrollToEnd();
    }, 1500);
  }
  render() {
    return (
      <View style={{ flex: 1 }}>
        <FlatList
          data={[1, 2, 3, 4, 5, 6, 7, 8]}
          ref={(ref) => (this.FlatListRef = ref)}
          renderItem={({ item }) => {
            return (
              <View
                style={{
                  height: 140,
                  width: 400,
                  backgroundColor: "yellow",
                  alignItems: "center",
                  justifyContent: "center",
                }}
              >
                <Text>{item}</Text>
              </View>
            );
          }}
        />
      </View>
    );
  }

}

Upvotes: 0

Rajan
Rajan

Reputation: 1568

scrollToListPosition = (index) => {
  const itemOffset = this.getItemOffset(index)
  this.flatListRef.scrollToOffset({ animated: false, offset: itemOffset })
}

getItemOffset = (index) => {
  let heightsum = 0
  for (i = 0; i < index; i++) {
    heightsum = heightsum + this.itemHeight[i]
  }
  return heightsum
}


render(){
  return (
    <FlatList
      ref={(ref) => { this.flatListRef = ref; }}
      data={postList}
      keyExtractor={(item, index) => item._id}
      horizontal={false}
      extraData={this.state}
      keyboardShouldPersistTaps='always'
      refreshing={this.props.isRefreshing}
      onRefresh={this.handleRefresh}
      onEndReached={this.handleLoadMore}
      getItemLayout={(data, index) => (
        { length: this.getLength(index), offset: this.getLength(index) * index, index }
      )}
      renderItem={({ item, index }) => {
        return (
          <View onLayout={(event) => {
            var { height } = event.nativeEvent.layout;
            this.itemHeight[index] = height
          }}
          >
            <ListCommon
              key={index}
              item={item}
              index={index}
              parentFlatList={this}
              data={item}
              instance={this.props.commanAction}
              tag={this.state.tag}
              changeRoute={this.props.changeRoute}
            />
          </View>
        );
      }}
    />
  )
}

getLength = (index) => {
  if (this.itemHeight[index] === undefined) {
    return 0;
  }
  return this.itemHeight[index]
}

Upvotes: 0

learner
learner

Reputation: 234

You can use Javascript method to reverse to show your messages from end

messages.reverse()

Upvotes: 0

Related Questions