web-dev-qa-db-fra.com

React accès natif aux références dans un composant personnalisé

J'ai un TextInput personnalisé. Lorsque je modifie le premier TextInput et que je clique sur "Suivant" dans le clavier, je veux qu'il concentre le second TextInput. J'ai déjà cherché dans Stack Overflow et il semble que je puisse le faire en utilisant ref. Cependant, je ne sais pas comment faire cela avec un TextInput personnalisé.

Voici mon code de base 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

Et voici ma classe Parent qui l'appelle:

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

En ce moment, lorsque j'appuie sur le Next du clavier, après avoir sélectionné le firstName, j'ai eu une exception:

undefined n'est pas un objet (évaluation de '_this2.refs.lastNameInput.focus')

Je ne suis pas sûr de ce que j'ai fait de mal là-bas .. Toute aide est appréciée. :)

19
prinnny

Commençons par le composant 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>
    );
}}

Ici, j'ai un exemple customTextInput. Les éléments importants à noter ici sont la méthode componentDidMount (), focus () et la propriété ref dans la vue TextInput dans la méthode de rendu.

  1. la méthode componentDidMount () transmet la référence de l'ensemble du composant CustomTextInput à son composant parent. Par cette référence, nous appellerons la méthode de focus du composant CustomTextInput à partir du composant parent.

  2. la méthode focus () concentre ici le textInput à l'intérieur du composant CustomTextInput en utilisant la référence du composant TextInput à l'intérieur du composant CustomTextInput.

  3. La propriété ref de TextInput stocke la référence de TextInput. Cette référence est utilisée par la méthode focus ().

Voyons maintenant le composant parent

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>
    );
}}

Ici, dans le composant parent, nous stockons la référence de chaque CustomTextInput avec la propriété onRef et lorsque le bouton de soumission du clavier est enfoncé, nous appelons la méthode de focus du prochain CustomTextInput et la méthode de focus de CustomTextInput concentre le TextInput à l'intérieur du composant enfant.

21
Supto

essaye ça:

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

Voici une solution qui a fonctionné pour moi - fondamentalement, vous faites une référence dans votre composant personnalisé, auquel vous pouvez accéder à partir de votre référence dans votre composant parent:

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

Et dans le composant parent:

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