poikkeus
poikkeus

Reputation: 193

React Native and right way to handle TextInput data?

I am making an app with react-native-maps and now I'm adding an UI.

I have faced this problem that I cannot change the text on an TextInput if the Value is the same as the value which will be updated on onChangeText. It gets emptied while I type.

I solved this by adding this.forceUpdate() right after changing the value, but this makes the app lag a bit and markers on the map are blinking when I type text.

The value is sometimes changed by code but sometimes its edited by user and read by code. What is the right way to handle this? forceUpdate doesn't feel right...

<TextInput
    keyboardType={'numeric'}
    style = {styles.textInput}
    value = {this.state.tmpCustomer.phoneNumber}                    
    onChangeText ={(text) => {this.state.tmpCustomer.phoneNumber=text; this.forceUpdate()}}
/>

Upvotes: 1

Views: 5277

Answers (3)

j.doe
j.doe

Reputation: 1254

I was experiencing performance issues with React Native's TextInput too. I solved this by using defaultValue as opposed to value, and allowing the component to re-render only when a focus/blur event occurs using shouldComponentUpdate().

See below for an example.

export default class TextField extends React.Component {
    state = {
        value: '',
        touched: false
    };

    handleChange = (text) => {
        this.setState({
            value: text
        });
    };

    handleFocus = () => {
        this.setState({
            touched: true
        });
    };

    handleBlur = () => {
        this.setState({
            touched: false
        });
    };

    shouldComponentUpdate(nextProps, nextState) {
        const currentTouched = this.state.touched;
        const nextTouched = nextState.touched;

        // Re-render when the user has focused or unfocused the text field
        return (currentTouched !== nextTouched);
    }

    render() {
        const {value} = this.state;

        return (
            <TextInput
                // Use defaultValue to set the text field's default value upon render
                defaultValue={value}
                onFocus={this.handleFocus}
                onBlur={this.handleBlur}
                onChangeText={this.handleChange}
            />
        );
    }
}

Upvotes: 0

poikkeus
poikkeus

Reputation: 193

I fixed the lag by switching onChangeText to onEndEditing and removed value and used setNativeProps to change the text. https://facebook.github.io/react-native/docs/direct-manipulation.html

Upvotes: 4

Piotr Sołtysiak
Piotr Sołtysiak

Reputation: 1006

Have you tried this?

<TextInput
    keyboardType={'numeric'}
    style = {styles.textInput}
    value = {this.state.tmpCustomer.phoneNumber}                    
    onChangeText ={(text) => { 
        const {tmpCustomer} = this.state;
        tmpCustomer.phoneNumber = text;
        this.setState({tmpCustomer : tmpCustomer});
    }}
/>

setState() will update compnent, so there is no need to forceUpdate (which usage, to be honest, you should avoid)

Upvotes: 2

Related Questions