Skip to content

Migration guide for 2.0

Satyajit Sahoo edited this page Sep 6, 2018 · 9 revisions

In React Native Paper 2.0, we redesigned various components to match the updated material design guidelines. We also worked on making existing components more flexible. Some of these changes needed changes in the API because the previous API was too limiting. We have tried to cover the changes in this guide so you can update your code to the new version.

Since there are a lot of changes, we are also working on a codemod so these changes can be automated with minimal manual work.

The previous version will still receive bug fixes, so you don't have to upgrade right away. But it won't receive any new features.

So here are the list of breaking changes:

Various components were renamed and/or grouped under a namespace

  • ToolbarAppbar.Header
  • Toolbar.ActionAppbar.Action
  • ToolbarBackActionAppbar.BackAction
  • ToolbarContentAppbar.Content
  • CardActionsCard.Actions
  • CardContentCard.Content
  • CardCoverCard.Cover
  • DialogActionsDialog.Actions
  • DialogContentDialog.Content
  • DialogScrollAreaDialog.ScrollArea
  • DialogTitleDialog.Title
  • DrawerItemDrawer.Item
  • DrawerSectionDrawer.Section
  • FABGroupFAB.Group
  • ListAccordionList.Accordion
  • ListItemList.Item
  • ListSectionList.Section
  • RadioButtonGroupRadioButton.Group
  • PaperSurface

SearchBar was removed in favour of Searchbar (8c5bc51)

Update your imports to use Searchbar instead of SearchBar.

Change this:

import { SearchBar } from 'react-native-paper';

To this:

import { Searchbar } from 'react-native-paper';

React elements are no longer supported in the icon prop (65ad2a0)

If you are passing a React element to the icon prop, change it to a function returning an element instead.

Change this:

<Button
  icon={(
    <Image
      source={require('../assets/chameleon.jpg')}
      style={{ width: 16, height: 16 }}
    />
  )}
>
  Press me
</Button>

To this:

<Button
  icon={({ size, color }) => (
    <Image
      source={require('../assets/chameleon.jpg')}
      style={{ width: size, height: size, tintColor: color }}
    />
  )}
>
  Press me
</Button>

Paper was renamed to Surface (3485402)

Change this:

import { Paper } from 'react-native-paper';

To this:

import { Surface } from 'react-native-paper';

Button was redesigned with API changes (37091c7)

The raised prop has been removed in favor of a mode prop.

If you have raised={true} and primary={true}, update it to mode="contained".

Change this:

<Button raised primary>Click me</Button>

To this:

<Button mode="contained">Click me</Button>

If you have raised={true} and primary={false} (default), update it to mode="outlined".

Change this:

<Button raised>Click me</Button>

To this:

<Button mode="outlined">Click me</Button>

The primary prop has been removed. The text color and the background color is always primary color in mode="text" and mode="outlined" respectively. To change this behavior, use the color prop to customize the color.

Default margins from various components has been removed (9ad9532)

Earlier, few of the components included a margin by default and you had to pass a style prop to override them, while most other components didn't include a margin. Now the default margin is removed for consistency.

Default margin was removed from the following components:

  • Button
  • Card
  • Chip
  • Searchbar

If you want to keep previous behavior, you can pass a style with margin: 4 to these components.

The dark prop was dropped in various components (c3bf6b0)

In some components, the dark prop used to control whether the icon will be light or dark. Now you need to use the color prop instead which is more flexible. By default, the color is determined automatically depending on how dark the background color is.

The prop was removed in the following components:

  • FAB
  • ToolbarAction (now Appbar.Action)
  • ToolbarBackAction (now Appbar.BackAction)
  • ToolbarContent (now Appbar.Content)

The color prop was removed from DrawerItem (734cd98)

Instead of the color prop, you can now customize theme's primary and text colors to customize drawer item's appearance.

The duration statics in Snackbar were changed (bc5d967)

Snackbar.DURATION_SHORT (2500ms), Snackbar.DURATION_LONG (3500ms) and Snackbar.DURATION_INDEFINITE were removed in favor of Snackbar.DURATION_SHORT (4000ms), Snackbar.DURATION_MEDIUM (7000ms) and Snackbar.DURATION_LONG (10000ms). Either migrate to the new values in your code or pass milliseconds directly to keep the old behavior.

Change this:

<Snackbar visible={this.state.visible} duration={Snackbar.DURATION_SHORT}>Hey there</Snackbar>

To this:

<Snackbar visible={this.state.visible} duration={2500}>Hey there</Snackbar>

Toolbar was split into Appbar and Appbar.Header (d9a3d77)

The difference between Appbar and Appbar.Header is that Appbar.Header applies extra space at the top to compensate for translucent statusbar, while Appbar doesn't apply any tweaks.

If you're using Toolbar, you can replace it with Appbar.Header in your code.

Chip was redesigned with API changes (1d3276a)

The onDelete prop of the Chip component was renamed to onClose.

Change this:

<Chip icon="info" onPress={this._handlePress} onDelete={this._handleDelete}>
  Example Chip
</Chip>

To this:

<Chip icon="info" onPress={this._handlePress} onClose={this._handleDelete}>
  Example Chip
</Chip>

In addition, the following props were added:

  • mode
  • avatar
  • selected
  • disabled

TextInput was redesigned with API changes (f1cde8a)

The TextInput component now includes a mode prop which controls the appearance according to material design docs. By default, it's flat. If you want the outline mode, add the mode prop to your inputs.

Change this:

<TextInput
  label="Email"
  value={this.state.text}
  onChangeText={text => this.setState({ text })}
/>

To this:

<TextInput
  mode="outline"
  label="Email"
  value={this.state.text}
  onChangeText={text => this.setState({ text })}
/>

Modal-like components are no longer rendered on top of everything else (1c8cf5c)

Some components such as Dialog need to be rendered on top of everything else. Previously, we had an internal component called Portal which took care of this. However, it doesn't play well with navigation libraries which keep old screens rendered when you navigate away.

The following components used to use Portal:

  • Dialog
  • FAB.Group
  • Modal
  • Snackbar

We no longer use Portal by default so that navigators can provide a better way of rendering content on top of the screen. We also export the Portal component now, so if you want to keep the previous behavior, you can wrap your component in Portal.

Change this:

<Dialog
  visible={this.state.visible}
  onDismiss={this._hideDialog}>
  ...
</Dialog>

To this:

<Portal>
  <Dialog
    visible={this.state.visible}
    onDismiss={this._hideDialog}>
    ...
  </Dialog>
</Portal>

The checked prop was removed in favor of a status prop in Checkbox and RadioButton (3b09171)

Instead of a checked prop, which is boolean, Checkbox and RadioButton now accept a status prop to be able to support additional states such as indeterminate.

Change this:

<Checkbox
  checked={checked}
  onPress={this._handlePress}
/>

To this:

<Checkbox
  status={checked ? 'checked' : 'unchecked'}
  onPress={this._handlePress}
/>

The icon and avatar props of List.Item and List.Accordion were replaced with left and right props (27c196f)

The icon and avatar props of List.Item was limited because it didn't let you render custom components such as switches. It was also confusing because the icon could render on left or right depending on whether avatar is specified. The left and right props make it easier to understand and provide more flexibility regarding what you can render.

If your List.Item has only the icon prop, change this:

<ListSection.Item icon="event" title="Some title" />

To this:

<ListSection.Item
  left={props => <ListSection.Icon {...props} icon="event" />}
  title="Some title"
/>

If your List.Item has only the avatar prop, change this:

<ListSection.Item
  avatar={
    <Image
      source={require('../assets/avatar.png')}
      style={styles.avatar}
    />
  }
  title="Some title"
  description="Some description"
/>

To this:

<ListSection.Item
  left={() =>
    <Image
      source={require('../assets/email-icon.png')}
      style={styles.avatar}
    />
  }
  title="Some title"
  description="Some description"
/>

If your List.Item has both the icon and avatar props, change this:

<ListSection.Item
  icon="event"
  avatar={
    <Image
      source={require('../assets/avatar.png')}
      style={styles.avatar}
    />
  }
  title="Some title"
  description="Some description"
/>

To this:

<ListSection.Item
  left={() =>
    <Image
      source={require('../assets/email-icon.png')}
      style={styles.avatar}
    />
  }
  right={props => <ListSection.Icon {...props} icon="event" />}
  title="Some title"
  description="Some description"
/>

The tintColor props were renamed to just color in BottomNavigation (2d7f50c)

The renderIcon and renderLabel props now receive a color property in the arguments instead of tintColor for consistency with other components


If this guide is missing something or you spot an error, please open an issue in the repo.

Clone this wiki locally