2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ReactNativeでQRコード生成

Last updated at Posted at 2019-10-24

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]
(https://ja.wikipedia.org/wiki/QR%E3%82%B3%E3%83%BC%E3%83%89#QR%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E7%94%A8%E8%AA%9E)

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

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

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

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?