ReactNativeでQRコード生成


QRコードを生成するライブラリはいくつかありますが、Canvasに依存していたり、SVGとして出力するしかなかったりするため、ReactNativeで使おうとすると問題があるケースが多いです。

簡単すぎる記事で申し訳ないですが、ReactNativeとの相性が良さそうなqrcode-generatorを使ったコンポーネント例を載せておきます。

QRCode.js
import React from 'react';
import PropTypes from 'prop-types';
import { Image } from 'react-native';
import qrcode from 'qrcode-generator';

export default class QRCode extends React.PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      size: null
    };
    this.onLayout = this.onLayout.bind(this);
  }

  componentWillReceiveProps(nextProps, nextContext) {
    if (nextProps.size !== this.props.size) {
      this.setState({
        size: null
      });
    }
  }

  onLayout(e) {
    const { width } = e.nativeEvent.layout;
    if (this.state.size !== width) {
      this.setState({ size: width });
    }
  }

  render() {
    const { data, cellSize, margin, typeNumber, errorCorrectionLevel } = this.props;
    const size = this.state.size || this.props.size;
    const QRCode = qrcode(typeNumber, errorCorrectionLevel);
    QRCode.addData(data);
    QRCode.make();
    let calculatedCellSize = cellSize;
    if (typeof calculatedCellSize !== 'number' && typeof size === 'number') {
      calculatedCellSize = typeof margin === 'number' ? Math.round((size - margin * 2) / QRCode.getModuleCount())
        : Math.round(size / (QRCode.getModuleCount() + 8));
    }
    const uri = QRCode.createDataURL(calculatedCellSize, margin);
    return (
      <Image
        key={uri}
        onLayout={this.onLayout}
        style={{
          width: size,
          aspectRatio: 1
        }}
        source={{ uri }}
      />
    );
  }
}

QRCode.defaultProps = {
  typeNumber: 0 // 自動
};

QRCode.propTypes = {
  data: PropTypes.string.isRequired, // データ文字列
  size: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, // 画像の大きさ
  cellSize: PropTypes.number, // セルの大きさ
  margin: PropTypes.number, // 余白の大きさ
  typeNumber: PropTypes.number, // 型番
  errorCorrectionLevel: PropTypes.string.isRequired // 誤り訂正レベル
};

propsの型番、誤り訂正レベルについてはこちらを参照してください。

QRコード - Wikipedia

セルの大きさ、余白、型番は何も入れなければ自動的に決定されるようになりますので、基本的に非推奨です。
sizeには文字列(100%など)を入れた場合にも自動で画像の解像度が調整されるようにしてみました。

シンプルなQRコードの生成はこれで最低限かつ安定してできますが、色を変えたりロゴを配置したりするのには対応していないので、その点ほかのライブラリ(Expoだとそれぞれ不具合ありですがreact-native-qrcode-svgreact-native-qrcode)に劣ります。

Canvasを使った記事に追記しました