目的
- input項目の値を、submitしたらクリアする、という処理にとてもハマった
- reactでのdom操作の考え方の一端を学ぶことができた
- 今回の例はinputだけだが、異なるdom要素でも同様の考え方になると思うので、整理する
やりたいこと
- react-nativeで、input項目を用意し、submitしたらinputフィールドのvalueをクリアしたい
問題の事象
- 普通のhtmlではないため、getElementById、などでinput要素を取ることができない
対策
考え方
- 要素にrefを定義しておいて、それを元にjs側で扱う、という操作をする
- document.getElementBy...の代わりに、refを使う
- Reactから
createRef()
で、input
(名称は任意)というタグ名で変数を作り、 - dom要素のInputのref属性に設定する
const input = React.createRef();
<Input
ref={input}
...
/>
- dom要素が扱えるものは、コンポーネントに何を使っているかによるが、
今回react-native-elementsを使っているので、ドキュメントに定義がある
https://react-native-elements.github.io/react-native-
- inputが使えるメソッド
input.current.focus();
input.current.blur();
input.current.clear();
input.current.isFocused();
input.current.setNativeProps({ value: 'hello' });
input.current.shake();
クラスで実際に使うときに
- 考え方としては上記だが、
- このままだと、onPressのスコープとrefをしているrenderのスコープがずれてしまう場合(例の通り)refが取れないので、
- クラスで変数を持ち、constructorでrefを設定しておく
参考 Ref と DOM
https://ja.reactjs.org/docs/refs-and-the-dom.html
サンプルのクラス
import React from 'react';
import { StyleSheet, Text, View, FlatList, Image,Dimensions, Alert,KeyboardAvoidingView } from 'react-native';
import { Button, Input } from 'react-native-elements';
export default function(props) {
return <CommentList {...props} navigation={navigation} />;
}
class CommentList extends React.Component {
state = {
comment: ''
}
constructor(props) {
super(props);
// input項目のバインド
this.onChangeComment = this.onChangeComment.bind(this);
// domへアクセスするためのrefを全体に見えることろで定義
this.ref = React.createRef();
}
submit = () => {
console.log('Submit')
// input項目を初期化 refで要素を取得する
const node = this.ref.current;
node.clear(); // Dom要素をここで操作している
}
render() {
// input要素へのアクセスのためのrefを設定する
const input = React.createRef();
<Input ref={this.ref} label="コメント" style={styles.input} onChangeText={this.onChangeComment}/>
<Button title="送信" onPress={this.submit}/>
}
}
const styles = StyleSheet.create({省略})