1つも依存がないピュアなオシャコンポーネントを作った


成果物

リポジトリはこちら

Example

import React from 'react';
import ParallaxView from 'react-native-parallax-header-view';
import {StyleSheet, ScrollView, View, Text} from 'react-native';

import {
  LearnMoreLinks,
  Colors,
  DebugInstructions,
  ReloadInstructions,
} from 'react-native/Libraries/NewAppScreen';

const App: () => React$Node = () => {
  const backgroundStyle = {
    opacity: 0.2,
    overflow: 'visible',
    resizeMode: 'cover',
    marginLeft: -128,
    marginBottom: -192,
  };

  const headerStyle = {
    fontSize: 40,
    fontWeight: '600',
    textAlign: 'center',
    paddingTop: 80,
    color: Colors.black,
  };

  return (
    <ParallaxView
      backgroundSource={require('./logo.png')}
      windowHeight={250}
      backgroundStyle={backgroundStyle}
      headerStyle={headerStyle}
      header={<Text style={headerStyle}>Welcome to React</Text>}>
      <View>
        <ScrollView
          contentInsetAdjustmentBehavior="automatic"
          style={styles.scrollView}>
          <View style={styles.body}>
            <View style={styles.sectionContainer}>
              <Text style={styles.sectionTitle}>Step One</Text>
              <Text style={styles.sectionDescription}>
                Edit <Text style={styles.highlight}>App.js</Text> to change this
                screen and then come back to see your edits.
              </Text>
            </View>
            <View style={styles.sectionContainer}>
              <Text style={styles.sectionTitle}>See Your Changes</Text>
              <Text style={styles.sectionDescription}>
                <ReloadInstructions />
              </Text>
            </View>
            <View style={styles.sectionContainer}>
              <Text style={styles.sectionTitle}>Debug</Text>
              <Text style={styles.sectionDescription}>
                <DebugInstructions />
              </Text>
            </View>
            <View style={styles.sectionContainer}>
              <Text style={styles.sectionTitle}>Learn More</Text>
              <Text style={styles.sectionDescription}>
                Read the docs to discover what to do next:
              </Text>
            </View>
            <LearnMoreLinks />
          </View>
        </ScrollView>
      </View>
    </ParallaxView>
  );
};

const styles = StyleSheet.create({
  scrollView: {
    backgroundColor: Colors.lighter,
  },
  body: {
    backgroundColor: Colors.white,
  },
  sectionContainer: {
    marginTop: 32,
    paddingHorizontal: 24,
  },
  sectionTitle: {
    fontSize: 24,
    fontWeight: '600',
    color: Colors.black,
  },
  sectionDescription: {
    marginTop: 8,
    fontSize: 18,
    fontWeight: '400',
    color: Colors.dark,
  },
  highlight: {
    fontWeight: '700',
  },
});

export default App;

こんな感じでjsだけで完結します。ライブラリの中身も依存関係はなく1つのファイルのみで完結しています。
サクッとヘッダ画像を伴ったプロフィールのスクリーンだったりなんなりを作るのに適しているんじゃないかなと思います。

なぜわざわざ作り替えたのか

ひょっとしたら勘の良い方は気がついていたかもしれませんが
https://github.com/lelandrichardson/react-native-parallax-view

このリポジトリとかなり似たような内容です。というかほぼ同じ。API(Props)の部分は少し変えてたり、リファクタリングはしていたりしますがやっていることはだいたいおんなじです。

作り替えた理由としては大きく以下二つ。

  • 完全にメンテナンスがされてない

issueもPRも乱立しているのにマージされていません。
筆者もissueと同じ問題に出くわしましたが、解決されずに放置されていました。Collaboratorの追加もされてない様子でした。4-5年間ほどは動きがないようです。
実際issueに上がっている内容もバージョンが古すぎると言った内容が多く見受けられました。

  • 純粋に便利なライブラリなのできちんとOSSとして続けていたい

もともとこのライブラリを見つけたのもこの記事
【React Native】良さげなコンポーネント紹介 - Qiita
がきっかけでした。この記事は僕としてもいいまとめ記事だなと思っていて自分のアプリを作った時に参考にしようと思い、今回のライブラリに出くわしました。

ライブラリの陳腐化は止めなければならない

Railsに始まりreact-nativeの恩恵に預かりエンジニアとして生きていくという人生の大きな軸になっているOSSはもはや切っても切り離せないほど僕の人生に癒着しています。

もちろん元のライブラリの作成者には畏敬の念を払いつつ(今回のライブラリを作成する際、作成者に対してライブラリを作る旨は連絡しています。もしまたメンテナンスする気があるなら、僕のライブラリとオリジナルのライブラリの差分を抽出してPRにする旨も連絡しています。)、MITライセンスだったこともありコミュニティに少しでも貢献できるようにライブラリの作成に踏み切りました。

今回が初めてのnpmパッケージの公開ですが、react-nativeには大きな可能性があると確信しています。

興味を持ってくれた方はどんどんどんどんバグ報告やコラボレータも増やしたいと考えています。
お待ちしております🤙