💭

React Nativeで文字列を扱う時に使ったテクニック

2022/04/26に公開

株式会社FUNEEでCONCRUを開発中のどんちゃんです。

ReactNative(Expo)を1から学習して1年数ヶ月。

プロダクトの開発が落ち着いてきたので、スキマ時間を使って、CONCRU開発で学んだノウハウや、テクニックを小出しにしていこうと思います。

今回は、最初の記事ということで、初歩的な、文字列を扱う時のテクニック を紹介します。

文字を任意の箇所で折り返す

ReactNativeではTextコンポーネントが提供されています。
https://reactnative.dev/docs/text

上記ドキュメントに書いてあることではありますが、可読性を担保するのであれば、コンポーネントごとにレンダリングするのが良いです。
各Textコンポーネントは、Viewコンテナーの子にするのがミソです。

import React, { Text, View } from 'react-native'

export const ExampleComponent = () => {
  return (
    <View>
      <Text>一行目</Text>
      <Text>二行目</Text>
      <Text>三行目</Text>
    </View>
  )
}

他の実現方法

「ReactNative Text 改行」なんかでググると、テンプレートリテラルや、 改行コード(¥n)を使う方法を解説してる記事が多いですが、僕的には読みづらいと思ってます。

応用


例えば、この「リストを作る」ボタンはこういう風に作ってます(コードは説明用に加工してます)

mapでレンダリングしてもOKです。

export const FAB = ({ onPress, name, label }: Props) => {
  return (
    <TouchableOpacity style={[styles.float_button]} onPress={onPress}>
      <View style={{ alignItems: 'center' }}>
        <FontAwesome5 name={name} size={18} color={colors.white} />
        <Spacer size={4} axis="vertical" />
        {label.map((m, i) => {
          return (
            <Text key={i} style={[styles.label]}>
              {m}
            </Text>
          )
        })}
      </View>
    </TouchableOpacity>
  )
}

条件付きレンダーの罠

Reactでは、こういう風に if文が如く、 返すコンポーネントを条件付きレンダリングできます。

render() {
  const count = 0;
  return (
    <div>
      {count && <h1>Messages: {count}</h1>}
    </div>
  );
}

https://ja.reactjs.org/docs/conditional-rendering.html#inline-if-with-logical--operator

これを参考にReact Native向けに書き換えてみたコードです。

import React, { Text, View } from 'react-native'

type Props = {
  description?: string
}
export const ExampleComponent = ({ description = '' }: Props) => {
  return <View>{description && <Text>{description}</Text>}</View>
}

今回のミソは、 description の規定値が空文字(文字列型)であることです。上記では、このようなエラーが出ます。

Error: Text strings must be rendered within a <Text> component.

原因と対応

原因は、descriptionがfalsyな値のために、 Viewの子が JSX.Elementではなく、空文字になってしまいます。

Reactでは問題ないのがハマりポイントでした。

対応方法ですが、空文字(文字列型)であることが原因なのでこうしてあげます。

そもそも規定値が空文字であること自体が考えものですが、今回は仕方ない…。

import React, { Text, View } from 'react-native'

type Props = {
  description?: string
}
export const ExampleComponent = ({ description = '' }: Props) => {
  return <View>{!!description && <Text>{description}</Text>}</View>
}

Discussion