web-dev-qa-db-ja.com

Reactカスタムコンポーネントのネイティブアクセス参照

カスタムTextInputがあります。最初のTextInputを編集してキーボードの[次へ]を押すと、2番目のTextInputにフォーカスが移動します。以前にスタックオーバーフローで検索したことがあり、refを使用して検索できるようです。しかし、カスタムTextInputでそれを行う方法はわかりません。

これが私の基本的なCustomTextInputコードです。

let CustomTextInput = React.createClass({
    propTypes: {
        refName: React.PropTypes.string,
        returnKeyType: React.PropTypes.string,
        onSubmitEditing: React.PropTypes.func
    },

    getDefaultProps: function(){
        return {
            refName: "",
            returnKeyType: "default",
            onSubmitEditing: () => {}
        }
    },

    render: function(){
        return(
            <View>
                <TextInput 
                    ref={this.props.refName}
                    returnKeyType={this.props.returnKeyType}
                    onSubmitEditing={this.props.onSubmitEditing}
                />
            </View>
        )
    }
});

module.exports = CustomTextInput

そして、それを呼び出す私の親クラスはここにあります:

let MyParent = React.createClass({
    render: function(){
        return(
            <View>
                <CustomTextInput
                    refName={'firstNameInput'},
                    returnKeyType={'next'}
                    onSubmitEditing={(event) => { 
                        this.refs.lastNameInput.focus();
                    }}
                />
                <CustomTextInput
                    refName={'lastNameInput'}
                />
            </View>
        )
    }
});

現在、キーボードでNextを押すと、firstNameを選択した後、例外が発生しました。

undefinedはオブジェクトではありません( '_this2.refs.lastNameInput.focus'を評価しています)

私はそこで何が間違っていたのかわかりません。どんな助けでもありがたいです。 :)

19
prinnny

CustomTextInputコンポーネントから始めましょう。

export default class CustomTextInput extends Component {

componentDidMount() {
    if (this.props.onRef != null) {
        this.props.onRef(this)
    }
}

onSubmitEditing() {
    this.props.onSubmitEditing();
}

focus() {
    this.textInput.focus()
}


render() {
    return (
        <View>
            <View style={this.state.isFocused ? styles.onFocusedStyle : styles.onBlurStyle}>
                <TextInput
                    ref={input => this.textInput = input}
                    onSubmitEditing={this.onSubmitEditing.bind(this)}
                />
            </View>

            <Text style={styles.errorMessageField}>{this.state.errorStatus && this.props.errorMessage}</Text>
        </View>
    );
}}

ここにサンプルのcustomTextInputがあります。ここで注意すべき重要な点は、renderメソッドのTextInputビューのcomponentDidMount()、focus()メソッド、およびrefプロパティです。

  1. componentDidMount()メソッドは、CustomTextInputコンポーネント全体の参照をその親コン​​ポーネントに渡します。その参照を通じて、CustomTextInputコンポーネントのfocusメソッドを親コンポーネントから呼び出します。

  2. ここでfocus()メソッドは、CustomTextInputコンポーネント内のTextInputコンポーネントの参照を使用して、CustomTextInputコンポーネント内のtextInputをフォーカスします。

  3. TextInputのrefプロパティは、TextInputの参照を格納します。この参照は、focus()メソッドで使用されます。

親コンポーネントを見てみましょう

export default class ParentComponent extends Component {
constructor(props) {
    super(props);

    this.focusNextField = this.focusNextField.bind(this);
    this.inputs = {};
}


focusNextField(id) {
    this.inputs[id].focus();
}

render() {
    return (
        <ScrollView
            contentContainerStyle={{paddingBottom:100}}
            keyboardDismissMode={'on-drag'}
            scrollToTop={true}>
            <View>
                    <View style={{marginTop: 10}}>
                        <CustomTextInput
                            onRef={(ref) => {
                                this.inputs['projectName'] = ref;
                            }}
                            onSubmitEditing={() => {
                                this.focusNextField('projectDescription');
                            }}
                            />
                    </View>
                    <View style={{marginTop: 10}}>
                        <CustomTextInput
                            onRef={(ref) => {
                                this.inputs['projectDescription'] = ref;
                            }}
                            onSubmitEditing={() => {
                                this.focusNextField('subDivision');
                            }}
                        />
                    </View>
                    <View style={{marginTop: 10}}>
                        <CustomTextInput
                            onRef={(ref) => {
                                this.inputs['subDivision'] = ref;
                            }}
                            onSubmitEditing={() => {
                                this.focusNextField('plan');
                            }}
                           />
                    </View>

                    <View style={{marginTop: 10}}>
                        <CustomTextInput
                            onRef={(ref) => {
                                this.inputs['plan'] = ref;
                            }}
                    </View>
            </View>
        </ScrollView>
    );
}}

ここで親コンポーネントに、onRefプロパティを持つ各CustomTextInputの参照を保存し、キーボードから送信ボタンが押されたときに、次のCustomTextInputのfocusメソッドを呼び出し、CustomTextInputのfocusメソッドが子コンポーネント内のTextInputにフォーカスします。

21
Supto

これを試して:

let AwesomeProject = React.createClass({
    onSubmitEditing:function(event){
        if (this.myTextInput !== null) {
          this.myTextInput.focus();
        }
    },
    render(){
        return(
            <View>
                <CustomTextInput
                    returnKeyType={'next'}
                    onSubmitEditing={this.onSubmitEditing}
                />
                <CustomTextInput
                    refName={(ref) => this.myTextInput = ref}
                />
            </View>
        )
    }
});
0
cityvoice
let CustomTextInput = React.createClass({
    componentDidMount() {
        // this is to check if a refName prop is FUNCTION; 
        if (typeof this.props.rex === "function") {
            this.props.refName(this.refs.inp);
        }
    }

    render: function() {
        return(
            <View>
                <TextInput ref={"inp"}/>
            </View>
        )
    }
});

let MyParent = React.createClass({
    render: function() {
        return (
            <View>
                <CustomTextInput
                    refName=(firstNameInput)=>this.firstNameInput=firstNameInput}
                />
            </View>
        )
    }
});
0
durga patra

ここで私のために働いたソリューションがあります—基本的には、カスタムコンポーネント内で参照を作成します。これは、親コンポーネントの参照からアクセスできます。

let CustomTextInput = React.createClass({
    propTypes: {
        refName: React.PropTypes.string,
        returnKeyType: React.PropTypes.string,
        onSubmitEditing: React.PropTypes.func
    },

    getDefaultProps: function(){
        return {
            refName: "",
            returnKeyType: "default",
            onSubmitEditing: () => {}
        }
    },

    render: function(){
        return(
            <View>
                <TextInput 
                    ref="input"
                    returnKeyType={this.props.returnKeyType}
                    onSubmitEditing={this.props.onSubmitEditing}
                />
            </View>
        )
    }
});

module.exports = CustomTextInput

そして親コンポーネントでは:

let MyParent = React.createClass({
    render: function(){
        return(
            <View>
                <CustomTextInput
                    refName={'firstNameInput'},
                    returnKeyType={'next'}
                    onSubmitEditing={(event) => { 
                        this.lastNameInput.refs.input.focus();
                    }}
                />
                <CustomTextInput
                    refName={ref => this.lastNameInput = ref}
                />
            </View>
        )
    }
});
0
Stefan Wüst