はじめに
React hooksにuseReducerというフックがありますが、様々な用途に使えます。今回はその一例として、React NativeのonChangeTextに利用する例を紹介します。
コード
const changeTextReducer = (_, text) => ({
text: text.toUpperCase(),
toolong: text.length > 10,
});
このようにreducerを準備します。毎回新しい値で書き換えるので、第一引数は捨てます。今回は、文字列を大文字に変換し、文字列の長さのチェックを追加しました。その他のバリデーションロジックを追加することもあるかと思います。
(何も変換処理をしないのであれば、reducerを使う意味はありません。)
const MyComponent = () => {
const [t1, setText1] = useReducer(changeTextReducer, { text: 'HELLO' });
const [t2, setText2] = useReducer(changeTextReducer, { text: 'WORLD' });
return (
<View>
<Text style={{ color: t1.toolong ? 'red' : 'black' }}>
{t1.text}
</Text>
<Text style={{ color: t2.toolong ? 'red' : 'black' }}>
{t2.text}
</Text>
<TextInput value={t1.text} onChangeText={setText1} />
<TextInput value={t2.text} onChangeText={setText2} />
</View>
);
};
コンポーネントではこのように使います。一つのreducerを複数のフックで使い回すことができます。
デモ
(執筆時点では、ExpoはReact hooksに対応していないため、上記デモではponyfillを用いています。)
おわりに
残念なことに、この書き方はReact Nativeでしか使えません。Web (React DOM)では、onChangeハンドラにはイベントが渡ってきてそのスコープ内で値を取り出さないといけないようです。