なにこれ
React NativeのTextタグで複数行テキストを書く場合、改行がめんどくさいですが、Tagged Template Literalsを使えばスッキリ書けます。 以下に動くソースコードを用意しています。
1. 公式リファレンス
まずはReact Nativeの公式リファレンスを見ます。
Textタグのプロパティには、改行をコントロールするようなものはなさそうでした。
ただ、サンプルとして載っていたコードには{"\n"}
で改行を指定していました。
とりあえず{"\n"}
を使えば、改行できそうです。
ただ、ちょっとめんどくさいし見た目が煩雑になってしまいます...
2. Stack Overflow
Stack Overflowで他に方法がないか調べたところ以下の質問がヒットしました。
1番いいねが多かった回答は公式リファレンスと同じ方法です。 React Nativeでは{"\n"}
で改行が普通なのでしょうか...
しかし、2番目に人気の回答は参考になりました。Template Literalsを使う方法です。
<Text>{`
Hi~
this is a test message.
`}</Text>
これは、良さそうです。ただ以下のようにインデントしたTextタグ中でキレイに書こうとすると、
<View>
<Text>{`
Hi~
this is a test message.
`}</Text>
</View>
画面上でもインデントされた状態になってしまいます...
3. Tagged Template Literalsと組み合わせる
しばらく考えて、Tagged Template Literalsを使うことにしました。 Tagged Template LiteralsはES6で出てきた新機能です。 タグ関数を定義して、Template Literalsをパースできます。 書き方も以下のようにスッキリしています。
<View>
<Text>{noIndent `
Hi~
this is a test message.
`}</Text>
タグ関数では以下のような感じです。
// Tagged Templates function
function noIndent(strs, ...placeholders) {
const original = placeholders.map((placeholder, i) => strs[i] + placeholder) + strs[strs.length - 1];
return removeIndent(original);
}
// for removing indents of each line and trims blank lines.
function removeIndent(value) {
const indentRemovedLines = value.split('\n').map((line) => line.replace(/^[^\S\n]+/g, ''));
const [firstLine, ...lines] = indentRemovedLines;
const [lastLine, ...reversedRestLines] = [...lines].reverse();
const restLines = [...reversedRestLines].reverse();
const firstLastLineTrimmed = [...(firstLine ? [firstLine] : []), ...restLines, ...(lastLine ? [lastLine] : [])].join('\n');
return firstLastLineTrimmed;
}
レンダリングもバッチリです。インデントは除去されています。
少し微妙なのは、タグ関数中でテキスト上下空行を問答無用で除去してしまっている点です。 タグ関数のオプション引数で渡して、除去するか選べるようにしたかったのですが、どうやらそれはTagged Template Literalsの仕様上できないようです。
最後に
以前Ionicについての記事を書きましたが、今後はReact Nativeをしばらく使いそうです。 モバイル開発においてネイティブの部分はさっぱりですが、React NativeはReactの書き方をそのまま使えるのがメリットとしては大きいです。 若干Reactと違う部分もあったりするので、今後はそこに関するノウハウを記事にできたらイイなと思っています🍅