React Native Fun

Little Atoms of React Native. Tips, Tricks, and How Tos.

Making an expanding TextInput

When you are accepting multiline input from a user, you sometimes want to TextInput to grow as the user enters more text. This allows it to only take up a small amount of space when no text has been entered, but then to grow when many lines are typed.

By default, the React Native TextInput component will have a fixed height and then scroll when the content doesn’t fit into the space provided anymore.

To solve this problem, we can write a simple component which wraps around the standard TextInput:

import React from 'react'
import { TextInput } from 'react-native'

export default class ExpandingTextInput extends React.Component {
  constructor (props) {
    super(props)
    this.state = {
      height: 0
    }
  }

  focus () {
    this.textInput && this.textInput.focus()
  }

  render () {
    return (
      <TextInput
        {...this.props}
        ref={(view) => (this.textInput = view)}
        multiline
        onContentSizeChange={(event) => {
          if (event && event.nativeEvent && event.nativeEvent.contentSize) {
            this.setState({
              height: event.nativeEvent.contentSize.height
            })
          }
          this.props.onContentSizeChange && this.props.onContentSizeChange(event)
        }}
        style={[this.props.style, { height: Math.max(35, this.state.height) }]}
      />
    )
  }
}

It can then be used with the same properties as the standard TextInput component:

<ExpandingTextInput
    style={styles.textInput}
    onChange={this._postTextChanged.bind(this)}
    maxLength={maxLength}
    value={postText}
    underlineColorAndroid='transparent'
    />

ExpandingTextInput wraps a standard TextInput but sets the height of it with a height style. When the user enters text into the TextInput, it will recalculate the size of the content inside it. If the size changes, it will call our onContentSizeChange callback, passing in the new content size. We can then update our height state to rerender and update the height style.

This gives us a text input which will expand with the user’s input like this: