2 min read

Developing react-native-image-viewer library for React Native

I was developing a simple twitter client with React Native recently. There will be many photos on user timeline, and I wanted to show them in fullscreen mode that users can swipe through. There were some libraries on npm site, but none of them fit well for my requirement, so I decided to develop one myself.

Setup

Let’s initialize the library project first:

$ npm init

And then install react and react-native packages from npm as peerDependencies:

"peerDependencies": {
    "react": "^15.2.1",
    "react-native": "^0.30.0"
}

Since the symlink support won’t land until React Native 0.32.0 release, so I use npm install /path/to/local/package_name to test my library, it’s tedious but it works.

As the library will show photos in fullscreen mode, we can just use Modal component provided by React Native.

By passing modalVisibility prop with value true, we will show the Modal:

<Modal transparent
  animationType={'fade'}
  visible={this.props.modalVisibility}
  >
  <View style={styles.wrapper}>
    <ImagePager navigationState={this.props.navigationState}
      closeModal={this.props.closeModal}
    />
  </View>
</Modal>

Also, we need a closeModal function that child component will use to hide our fullscreen Modal:

closeModal = () => {
  this.setState({
    modalVisibility: false
  })
}
render () {
  return (
    <ImageViewer modalVisibility={this.state.modalVisibility} closeModal={this.closeModal} />
  )
}

Remember, the photos can be swiped through. We could take them as scenes managed by a navigator. Since NavigationExperimental will finally replace Navigator when it becomes stable, I would prefer using NavigationExperimental in this library.

The UIExplorer has a great example showing how to make such a navigator with NavigationExperimental.

First, let’s define a navigationState describing our photos state:

{
  index: 0,
  routes: [
    {
      url: 'https://example.com/1.png'
    },
    {
      url: 'https://example.com/2.png'
    },
    {
      url: 'https://example.com/3.png'
    }
  ]
}

index controls which route in routes should be activated. When we swipe through the photos, we’re actually changing the index value in navigationState.

Of course we need to define how to update navigationState:

function reducer (state, action) {
  switch (action) {
    case 'back':
      return NavigationStateUtils.back(state)
    case 'forward':
      return NavigationStateUtils.forward(state)
  }
  return state
}

You should be familiar with the code if you had experience with redux.

When a user swipes the photo, the library would dispatch action to update navigationState, and scenes will be rerendered as the navigationState in component changes.

You can check the gif image below:

react-native-image-viewer

If you want to check more, please go to my github repository.

报告问题 修订

如果你有自建 https 代理的需求,欢迎尝试 Phantom,一键搭建,方便快捷。查看 demo